@ -8,7 +8,7 @@
* is that "<config_object_name>" must be considered *valid* by
* is that "<config_object_name>" must be considered *valid* by
* `BaseText.IsValidName()` standards, otherwise method will return `none`.
* `BaseText.IsValidName()` standards, otherwise method will return `none`.
*
*
* Copyright 2021 Anton Tarasenko
* Copyright 2021-2022 Anton Tarasenko
*------------------------------------------------------------------------------
*------------------------------------------------------------------------------
* This file is part of Acedia.
* This file is part of Acedia.
*
*
@ -26,7 +26,7 @@
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/
*/
class AcediaConfig extends AcediaObject
class AcediaConfig extends AcediaObject
dependson(AssociativeArray )
dependson(HashTable )
abstract;
abstract;
/**
/**
@ -65,7 +65,7 @@ class AcediaConfig extends AcediaObject
// In case it has a `none` value stored under some key - it means that value
// In case it has a `none` value stored under some key - it means that value
// was detected in config, but not yet loaded.
// was detected in config, but not yet loaded.
// Only its default value is ever used.
// Only its default value is ever used.
var private AssociativeArray existingConfigs;
var private HashTable existingConfigs;
// Stores name of the config where settings are to be stored.
// Stores name of the config where settings are to be stored.
// Must correspond to value in `config(...)` modifier in class definition.
// Must correspond to value in `config(...)` modifier in class definition.
@ -79,10 +79,10 @@ var public const bool supportsDataConversion;
/**
/**
* These methods must be overloaded to store and load all the config
* These methods must be overloaded to store and load all the config
* variables inside an `AssociativeArray ` collection. How exactly to store
* variables inside an `HashTable ` collection. How exactly to store
* them is up to each config class to decide, as long as it allows conversion
* them is up to each config class to decide, as long as it allows conversion
* into JSON (see `JSONAPI.IsCompatible()` for details).
* into JSON (see `JSONAPI.IsCompatible()` for details).
* Note that `AssociativeArray ` reference `FromData()` receives is
* Note that `HashTable ` reference `FromData()` receives is
* not necessarily the same one your `ToData()` method returns - any particular
* not necessarily the same one your `ToData()` method returns - any particular
* value boxes can be replaced with value references and vice versa.
* value boxes can be replaced with value references and vice versa.
* NOTE: DO NOT use `P()`, `C()`, `F()` or `T()` methods for keys or
* NOTE: DO NOT use `P()`, `C()`, `F()` or `T()` methods for keys or
@ -90,8 +90,8 @@ var public const bool supportsDataConversion;
* deallocated when necessary, so these methods for creating `Text` values are
* deallocated when necessary, so these methods for creating `Text` values are
* not suitable.
* not suitable.
*/
*/
protected function AssociativeArray ToData() { return none; }
protected function HashTable ToData() { return none; }
protected function FromData(AssociativeArray source) {}
protected function FromData(HashTable source) {}
/**
/**
* This method must be overloaded to setup default values for all config
* This method must be overloaded to setup default values for all config
@ -99,12 +99,6 @@ protected function FromData(AssociativeArray source) {}
*/
*/
protected function DefaultIt() {}
protected function DefaultIt() {}
protected static function StaticFinalizer()
{
__().memory.Free(default.existingConfigs);
default.existingConfigs = none;
}
/**
/**
* This reads all of the `AcediaConfig`'s settings objects into internal
* This reads all of the `AcediaConfig`'s settings objects into internal
* storage. Must be called before any other methods. Actual loading might be
* storage. Must be called before any other methods. Actual loading might be
@ -113,12 +107,12 @@ protected static function StaticFinalizer()
public static function Initialize()
public static function Initialize()
{
{
local int i;
local int i;
local Text nextName;
local Text nextName, lowerName ;
local array<string> names;
local array<string> names;
if (default.existingConfigs != none) {
if (default.existingConfigs != none) {
return;
return;
}
}
default.existingConfigs = __().collections.EmptyAssociativeArray ();
default.existingConfigs = __().collections.EmptyHashTable ();
names = GetPerObjectNames( default.configName, string(default.class.name),
names = GetPerObjectNames( default.configName, string(default.class.name),
MaxInt);
MaxInt);
for (i = 0; i < names.length; i += 1)
for (i = 0; i < names.length; i += 1)
@ -127,8 +121,11 @@ public static function Initialize()
continue;
continue;
}
}
nextName = __().text.FromString(NameToActualVersion(names[i]));
nextName = __().text.FromString(NameToActualVersion(names[i]));
if (nextName.IsValidName()) {
if (nextName.IsValidName())
default.existingConfigs.SetItem(nextName.LowerCopy(), none);
{
lowerName = nextName.LowerCopy();
default.existingConfigs.SetItem(lowerName, none);
lowerName.FreeSelf();
}
}
nextName.FreeSelf();
nextName.FreeSelf();
}
}
@ -178,6 +175,7 @@ public final static function bool NewConfig(BaseText name)
newConfig.DefaultIt();
newConfig.DefaultIt();
newConfig.SaveConfig();
newConfig.SaveConfig();
default.existingConfigs.SetItem(name, newConfig);
default.existingConfigs.SetItem(name, newConfig);
name.FreeSelf();
return true;
return true;
}
}
@ -214,15 +212,16 @@ public final static function bool Exists(BaseText name)
*/
*/
public final static function DeleteConfig(BaseText name)
public final static function DeleteConfig(BaseText name)
{
{
local AssociativeArray.Entry entry;
local AcediaObject value;
if (default.existingConfigs == none) {
if (name == none) return;
return;
if (default.existingConfigs == none) return;
}
entry = default.existingConfigs.TakeEntry(name);
name = name.LowerCopy();
if (entry.value != none) {
value = default.existingConfigs.TakeItem(name);
entry.value.ClearConfig();
if (value != none) {
value.ClearConfig();
}
}
__().memory.Free(entry.key );
__().memory.Free(name );
}
}
/**
/**
@ -235,7 +234,7 @@ public static function array<Text> AvailableConfigs()
{
{
local array<Text> emptyResult;
local array<Text> emptyResult;
if (default.existingConfigs != none) {
if (default.existingConfigs != none) {
return default.existingConfigs.Copy TextKeys();
return default.existingConfigs.Get TextKeys();
}
}
return emptyResult;
return emptyResult;
}
}
@ -250,7 +249,7 @@ public static function array<Text> AvailableConfigs()
*/
*/
public final static function AcediaConfig GetConfigInstance(BaseText name)
public final static function AcediaConfig GetConfigInstance(BaseText name)
{
{
local AssociativeArray .Entry configEntry;
local HashTable .Entry configEntry;
if (name == none) return none;
if (name == none) return none;
if (!name.IsValidName()) return none;
if (!name.IsValidName()) return none;
if (default.existingConfigs == none) return none;
if (default.existingConfigs == none) return none;
@ -265,6 +264,8 @@ public final static function AcediaConfig GetConfigInstance(BaseText name)
default.existingConfigs.SetItem(configEntry.key, configEntry.value);
default.existingConfigs.SetItem(configEntry.key, configEntry.value);
}
}
__().memory.Free(name);
__().memory.Free(name);
// We return value, so do not deallocate it
__().memory.Free(configEntry.key);
return AcediaConfig(configEntry.value);
return AcediaConfig(configEntry.value);
}
}
@ -284,10 +285,10 @@ public final static function AcediaConfig GetConfigInstance(BaseText name)
* For correctly implemented config objects should only return `none` if
* For correctly implemented config objects should only return `none` if
* their class was not yet initialized (see `self.Initialize()` method).
* their class was not yet initialized (see `self.Initialize()` method).
*/
*/
public final static function AssociativeArray LoadData(BaseText name)
public final static function HashTable LoadData(BaseText name)
{
{
local AssociativeArray result;
local HashTable result;
local AcediaConfig requiredConfig;
local AcediaConfig requiredConfig;
requiredConfig = GetConfigInstance(name);
requiredConfig = GetConfigInstance(name);
if (requiredConfig != none) {
if (requiredConfig != none) {
result = requiredConfig.ToData();
result = requiredConfig.ToData();
@ -309,7 +310,7 @@ public final static function AssociativeArray LoadData(BaseText name)
* allows for JSON deserialization (see `JSONAPI.IsCompatible()` for
* allows for JSON deserialization (see `JSONAPI.IsCompatible()` for
* details).
* details).
*/
*/
public final static function SaveData(BaseText name, AssociativeArray data)
public final static function SaveData(BaseText name, HashTable data)
{
{
local AcediaConfig requiredConfig;
local AcediaConfig requiredConfig;
requiredConfig = GetConfigInstance(name);
requiredConfig = GetConfigInstance(name);