From 11e0ef809ff0477c91bebeaf47ef83537d3108dc Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Tue, 3 Aug 2021 18:00:05 +0700 Subject: [PATCH] Change how Acedia's config swapping works --- sources/Avarice/Avarice.uc | 4 +-- sources/Avarice/Avarice_Feature.uc | 46 +++++----------------------- sources/Commands/Commands.uc | 6 ++-- sources/Commands/Commands_Feature.uc | 10 +++--- sources/Features/Feature.uc | 44 +++++++++++++------------- sources/Features/FeatureConfig.uc | 38 ++++++++++++++++------- 6 files changed, 66 insertions(+), 82 deletions(-) diff --git a/sources/Avarice/Avarice.uc b/sources/Avarice/Avarice.uc index 6460192..d0dc31f 100644 --- a/sources/Avarice/Avarice.uc +++ b/sources/Avarice/Avarice.uc @@ -32,7 +32,7 @@ struct AvariceLinkRecord // can be used in other configs to point at each link. // `address` must have form "host:port", where "host" is either ip or // domain name and "port" is a numerical port value. -var private config array link; +var public config array link; // In case Avarice utility is launched after link started trying open // the connection - that connection attempt will fail. To fix that link must @@ -41,7 +41,7 @@ var private config array link; // re-attempt opening connection. Setting value too low can prevent any // connection from opening, setting it too high might make you wait for // connection too long. -var private config float reconnectTime; +var public config float reconnectTime; protected function AssociativeArray ToData() { diff --git a/sources/Avarice/Avarice_Feature.uc b/sources/Avarice/Avarice_Feature.uc index cd0d4cc..5f03365 100644 --- a/sources/Avarice/Avarice_Feature.uc +++ b/sources/Avarice/Avarice_Feature.uc @@ -90,49 +90,17 @@ protected function OnDisabled() _.memory.FreeMany(createdLinks); } -protected function SwapConfig( - AssociativeArray previousConfigData, - AssociativeArray newConfigData) +protected function SwapConfig(FeatureConfig config) { - local int i; - local Text nextText; - local DynamicArray linksArray; - local AssociativeArray nextLink; - local Avarice.AvariceLinkRecord nextRecord; - // Simply restart all the links - for (i = 0; i < createdLinks.length; i += 1) - { - if (createdLinks[i] != none) { - createdLinks[i].FreeSelf(); - } - } - createdLinks.length = 0; - link.length = 0; - if (newConfigData == none) { + local Avarice newConfig; + newConfig = Avarice(config); + if (newConfig == none) { return; } - reconnectTime = newConfigData.GetFloat(P("reconnectTime")); + link = newConfig.link; + reconnectTime = newConfig.reconnectTime; + // For static `GetReconnectTime()` method default.reconnectTime = reconnectTime; - linksArray = newConfigData.GetDynamicArray(P("link")); - if (linksArray == none) { - return; - } - for (i = 0; i < linksArray.GetLength(); i += 1) - { - nextLink = linksArray.GetAssociativeArray(i); - if (nextLink == none) { - continue; - } - nextText = nextLink.GetText(P("name")); - if (nextText != none) { - nextRecord.name = nextText.ToPlainString(); - } - nextText = nextLink.GetText(P("address")); - if (nextText != none) { - nextRecord.address = nextText.ToPlainString(); - } - link[i] = nextRecord; - } } // Reply back any messages from "echo" service diff --git a/sources/Commands/Commands.uc b/sources/Commands/Commands.uc index 37def06..7321612 100644 --- a/sources/Commands/Commands.uc +++ b/sources/Commands/Commands.uc @@ -21,13 +21,13 @@ class Commands extends FeatureConfig perobjectconfig config(AcediaSystem); -var private config bool useChatInput; +var public config bool useChatInput; protected function AssociativeArray ToData() { local AssociativeArray data; data = __().collections.EmptyAssociativeArray(); - data.SetBool(__().text.FromString("useChatInput"), useChatInput, true); + data.SetBool(P("useChatInput"), useChatInput, true); return data; } @@ -38,7 +38,7 @@ protected function FromData(AssociativeArray source) } } -protected function Reset() +protected function DefaultIt() { useChatInput = true; } diff --git a/sources/Commands/Commands_Feature.uc b/sources/Commands/Commands_Feature.uc index 8c6542c..2782539 100644 --- a/sources/Commands/Commands_Feature.uc +++ b/sources/Commands/Commands_Feature.uc @@ -54,14 +54,14 @@ protected function OnDisabled() commandDelimiters.length = 0; } -protected function SwapConfig( - AssociativeArray previousConfigData, - AssociativeArray newConfigData) +protected function SwapConfig(FeatureConfig config) { - if (newConfigData == none) { + local Commands newConfig; + newConfig = Commands(config); + if (newConfig == none) { return; } - useChatInput = newConfigData.GetBool(P("useChatInput")); + useChatInput = newConfig.useChatInput; } /** diff --git a/sources/Features/Feature.uc b/sources/Features/Feature.uc index d37a25a..04933c7 100644 --- a/sources/Features/Feature.uc +++ b/sources/Features/Feature.uc @@ -137,28 +137,31 @@ protected function Finalizer() * (allocated). To set initial config on this `Feature`'s start - specify it * as a parameter to `EnableMe()` method. * + * Method will do nothing if `newConfigName` parameter is set to `none`. + * * @param newConfigName Name of the config to apply to the caller `Feature`. */ public final function ApplyConfig(Text newConfigName) { - local AssociativeArray newConfigData; - newConfigData = configClass.static.LoadData(newConfigName); - if (newConfigData == none) + local FeatureConfig newConfig; + if (newConfigName == none) { + return; + } + newConfig = configClass.static.GetConfigInstance(newConfigName); + if (newConfig == none) { _.logger.Auto(errorBadConfigData).ArgClass(class); // Fallback to "default" config newConfigName = _.text.FromString(defaultConfigName); configClass.static.NewConfig(newConfigName); - newConfigData = configClass.static.LoadData(newConfigName); + newConfig = configClass.static.GetConfigInstance(newConfigName); } - SwapConfig(currentConfig, newConfigData); - if (currentConfig != none) { - currentConfig.Empty(true); + else { + newConfigName = newConfigName.Copy(); } + SwapConfig(newConfig); _.memory.Free(currentConfigName); - _.memory.Free(currentConfig); - currentConfigName = newConfigName.Copy(); - currentConfig = newConfigData; + currentConfigName = newConfigName; } /** @@ -275,7 +278,7 @@ public static final function bool DisableMe() * * AVOID MANUALLY CALLING IT. */ -protected function OnEnabled() { } +protected function OnEnabled(){} /** * When using proper methods for enabling a `Feature`, @@ -283,24 +286,21 @@ protected function OnEnabled() { } * * AVOID MANUALLY CALLING IT. */ -protected function OnDisabled() { } +protected function OnDisabled(){} /** * Will be called whenever caller `Feature` class must change it's config * parameters. This can be done both when the `Feature` is enabled or disabled. * - * @param previousConfigData Config data that was previously set for this - * `Feature` class. `none` is passed iff config is set for the first time. - * @param newConfigData New config data that caller `Feature`'s class - * must use. Guaranteed to not be `none`. + * @param newConfigData New config that caller `Feature`'s class must use. + * We pass `FeatureConfig` value for performance and simplicity reasons, + * but to keep Acedia working correctly and in an expected way you + * MUST AVOID MODIFYING THIS VALUE IN ANY WAY WHATSOEVER. + * Guaranteed to not be `none`. * - * AVOID MANUALLY CALLING IT. - * DO NOT DEALLOCATE PASSED VALUES. - * DO NOT USE PASSED VALUES OUTSIDE OF THIS METHOD CALL. + * AVOID MANUALLY CALLING THIS METHOD. */ -protected function SwapConfig( - AssociativeArray previousConfigData, - AssociativeArray newConfigData) { } +protected function SwapConfig(FeatureConfig newConfig){} private static function SetListenersActiveStatus(bool newStatus) { diff --git a/sources/Features/FeatureConfig.uc b/sources/Features/FeatureConfig.uc index 6ff6079..080086c 100644 --- a/sources/Features/FeatureConfig.uc +++ b/sources/Features/FeatureConfig.uc @@ -17,9 +17,11 @@ * } * ``` * - * You should only define a new child class, along with implementing it's - * `FromData()`, `ToData()` and `DefaultIt()` methods and otherwise avoid - * directly using objects of this class. + * For each `Feature` you need to define a new child class, along with + * implementing it's `FromData()`, `ToData()` and `DefaultIt()` methods. + * You will also need to implement `Feature`'s `SwapConfig()` method that take + * an instance of `FeatureConfig` as a parameter. Other than that you should + * avoid directly using objects of this class. * Copyright 2021 Anton Tarasenko *------------------------------------------------------------------------------ * This file is part of Acedia. @@ -205,6 +207,27 @@ public static function array AvailableConfigs() return emptyResult; } +/** + * Returns `FeatureConfig` of caller class with name `name`. + * + * @param name Name of the config object, whos settings data is to + * be loaded. Case-insensitive. + * @return `FeatureConfig` of caller class with name `name`. + */ +public final static function FeatureConfig GetConfigInstance(Text name) +{ + local FeatureConfig requiredConfig; + if (default.existingConfigs == none) { + return none; + } + if (name != none) { + name = name.LowerCopy(); + } + requiredConfig = FeatureConfig(default.existingConfigs.GetItem(name)); + __().memory.Free(name); + return requiredConfig; +} + /** * Loads Acedia's representation of settings data of a particular config * object, given by the `name`. @@ -221,17 +244,10 @@ public final static function AssociativeArray LoadData(Text name) { local AssociativeArray result; local FeatureConfig requiredConfig; - if (default.existingConfigs == none) { - return none; - } - if (name != none) { - name = name.LowerCopy(); - } - requiredConfig = FeatureConfig(default.existingConfigs.GetItem(name)); + requiredConfig = GetConfigInstance(name); if (requiredConfig != none) { result = requiredConfig.ToData(); } - __().memory.Free(name); return result; }