Browse Source

Change how config is swapped for `Feature`s

Before config was allowed to be swapped while `Feature` was enabled,
which has led to a lot of loading code being moved into the
`SwapConfig()` method, making `Feature` initialization code way more
complex than it needed to be.

This patch forces `Feature` to get disabled before config swap. This
adds some verhead for swapping configs for already running `Feature`s,
but that's a small cost for way simpler implementations.
pull/12/head
Anton Tarasenko 2 years ago
parent
commit
087d8624d3
  1. 3
      sources/Aliases/Aliases_Feature.uc
  2. 28
      sources/Features/Feature.uc
  3. 38
      sources/LevelAPI/Features/Commands/Commands_Feature.uc
  4. 21
      sources/Users/Users_Feature.uc

3
sources/Aliases/Aliases_Feature.uc

@ -112,15 +112,12 @@ protected function SwapConfig(FeatureConfig config)
if (newConfig == none) {
return;
}
_.memory.Free(weaponAliasSource);
DropSources();
weaponAliasSource = GetSource(newConfig.weaponAliasSource);
colorAliasSource = GetSource(newConfig.colorAliasSource);
featureAliasSource = GetSource(newConfig.featureAliasSource);
entityAliasSource = GetSource(newConfig.entityAliasSource);
commandAliasSource = GetSource(newConfig.commandAliasSource);
LoadCustomSources(newConfig.customSource);
_.alias._reloadSources();
}
private function LoadCustomSources(

28
sources/Features/Feature.uc

@ -170,7 +170,6 @@ public static final function LoadConfigs()
/**
* Changes config for the caller `Feature` class.
*
* This method should only be called when caller `Feature` is enabled.
* To set initial config on this `Feature`'s start - specify it as a parameter
* to `EnableMe()` method.
*
@ -179,20 +178,17 @@ public static final function LoadConfigs()
*/
private final function ApplyConfig(BaseText newConfigName)
{
local Text configNameCopy;
local Text configNameCopy;
local FeatureConfig newConfig;
newConfig =
FeatureConfig(configClass.static.GetConfigInstance(newConfigName));
if (newConfig == none)
{
newConfig = FeatureConfig(configClass.static.GetConfigInstance(newConfigName));
if (newConfig == none) {
_.logger.Auto(errorBadConfigData).ArgClass(class);
// Fallback to "default" config
configNameCopy = _.text.FromString(defaultConfigName);
configClass.static.NewConfig(configNameCopy);
newConfig =
FeatureConfig(configClass.static.GetConfigInstance(configNameCopy));
}
else {
newConfig = FeatureConfig(configClass.static.GetConfigInstance(configNameCopy));
} else {
configNameCopy = newConfigName.Copy();
}
SwapConfig(newConfig);
@ -289,12 +285,8 @@ public static final function bool IsEnabled()
public static final function Feature EnableMe(BaseText configName)
{
local Feature myInstance;
myInstance = GetEnabledInstance();
if (myInstance != none)
{
myInstance.ApplyConfig(configName);
return myInstance;
}
DisableMe();
myInstance = Feature(__().memory.Allocate(default.class));
__().environment.EnableFeature(myInstance, configName);
return myInstance;
@ -336,8 +328,8 @@ protected function OnEnabled(){}
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.
* Will be called whenever caller `Feature` class must change it's config parameters.
* It is guaranteed that `Feature` will be disabled during this call.
*
* @param newConfigData New config that caller `Feature`'s class must use.
* We pass `FeatureConfig` value for performance and simplicity reasons,

38
sources/LevelAPI/Features/Commands/Commands_Feature.uc

@ -3,7 +3,7 @@
* parse their arguments into standard Acedia collection. It also allows to
* manage them (and specify limitation on how they can be called) in a
* centralized manner.
* Copyright 2021-2022 Anton Tarasenko
* Copyright 2021-2023 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
*
@ -117,6 +117,18 @@ protected function OnEnabled()
commandDelimiters[2] = _.text.FromString("[");
// Negation of the selector
commandDelimiters[3] = _.text.FromString("!");
if (useChatInput) {
_.chat.OnMessage(self).connect = HandleCommands;
}
else {
_.chat.OnMessage(self).Disconnect();
}
if (useMutateInput || emergencyEnabledMutate) {
_server.unreal.mutator.OnMutate(self).connect = HandleMutate;
}
else {
_server.unreal.mutator.OnMutate(self).Disconnect();
}
}
protected function OnDisabled()
@ -150,28 +162,8 @@ protected function SwapConfig(FeatureConfig config)
_.memory.Free(chatCommandPrefix);
chatCommandPrefix = _.text.FromString(newConfig.chatCommandPrefix);
allowedPlayers = newConfig.allowedPlayers;
if (useChatInput != newConfig.useChatInput)
{
useChatInput = newConfig.useChatInput;
if (newConfig.useChatInput) {
_.chat.OnMessage(self).connect = HandleCommands;
}
else {
_.chat.OnMessage(self).Disconnect();
}
}
// Do not make any modifications here in case "mutate" was
// emergency-enabled
if (useMutateInput != newConfig.useMutateInput && !emergencyEnabledMutate)
{
useMutateInput = newConfig.useMutateInput;
if (newConfig.useMutateInput) {
_server.unreal.mutator.OnMutate(self).connect = HandleMutate;
}
else {
_server.unreal.mutator.OnMutate(self).Disconnect();
}
}
useChatInput = newConfig.useChatInput;
useMutateInput = newConfig.useMutateInput;
}
/**

21
sources/Users/Users_Feature.uc

@ -80,7 +80,13 @@ protected function OnEnabled()
feature.RegisterCommand(class'ACommandUserGroups');
feature.FreeSelf();
}
LoadUserData();
if (_server.IsAvailable()) {
LoadUserData();
SetupPersistentData(usePersistentData);
} else {
_.logger.Auto(errNoServerCore);
return;
}
}
protected function OnDisabled()
@ -113,17 +119,6 @@ protected function SwapConfig(FeatureConfig config)
useDatabaseForGroupsData = newConfig.useDatabaseForGroupsData;
groupsDatabaseLink = newConfig.groupsDatabaseLink;
availableUserGroups = newConfig.localUserGroup;
ResetUploadedUserGroups();
if (IsEnabled())
{
if (!_server.IsAvailable())
{
_.logger.Auto(errNoServerCore);
return;
}
LoadUserData();
SetupPersistentData(usePersistentData);
}
}
/**
@ -2153,6 +2148,6 @@ defaultproperties
errDBBadRootUserGroupData = (l=LOG_Error,m="Database link \"%1\" (configured to load user group data in \"AcediaUsers.ini\") contains incompatible data.")
errDBBadLinkPointer = (l=LOG_Error,m="Path inside database link \"%1\" (configured inside \"AcediaUsers.ini\") is invalid.")
errDBDamaged = (l=LOG_Error,m="Database given by the link \"%1\" (configured inside \"AcediaUsers.ini\") seems to be damaged.")
errNoServerCore = (l=LOG_Error,m="Cannot start \"Users_Feature\", because no `ServerCore` was created.")
errNoServerCore = (l=LOG_Error,m="\"Users_Feature\" won't function properly, because no `ServerCore` was created.")
errDBContainsNonLowerRegister = (l=LOG_Error,m="Database given by the link \"%1\" contains non-lower case key \"%2\". This shouldn't happen, unless someone manually edited database.")
}
Loading…
Cancel
Save