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) { if (newConfig == none) {
return; return;
} }
_.memory.Free(weaponAliasSource);
DropSources();
weaponAliasSource = GetSource(newConfig.weaponAliasSource); weaponAliasSource = GetSource(newConfig.weaponAliasSource);
colorAliasSource = GetSource(newConfig.colorAliasSource); colorAliasSource = GetSource(newConfig.colorAliasSource);
featureAliasSource = GetSource(newConfig.featureAliasSource); featureAliasSource = GetSource(newConfig.featureAliasSource);
entityAliasSource = GetSource(newConfig.entityAliasSource); entityAliasSource = GetSource(newConfig.entityAliasSource);
commandAliasSource = GetSource(newConfig.commandAliasSource); commandAliasSource = GetSource(newConfig.commandAliasSource);
LoadCustomSources(newConfig.customSource); LoadCustomSources(newConfig.customSource);
_.alias._reloadSources();
} }
private function LoadCustomSources( private function LoadCustomSources(

28
sources/Features/Feature.uc

@ -170,7 +170,6 @@ public static final function LoadConfigs()
/** /**
* Changes config for the caller `Feature` class. * 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 set initial config on this `Feature`'s start - specify it as a parameter
* to `EnableMe()` method. * to `EnableMe()` method.
* *
@ -179,20 +178,17 @@ public static final function LoadConfigs()
*/ */
private final function ApplyConfig(BaseText newConfigName) private final function ApplyConfig(BaseText newConfigName)
{ {
local Text configNameCopy; local Text configNameCopy;
local FeatureConfig newConfig; local FeatureConfig newConfig;
newConfig =
FeatureConfig(configClass.static.GetConfigInstance(newConfigName)); newConfig = FeatureConfig(configClass.static.GetConfigInstance(newConfigName));
if (newConfig == none) if (newConfig == none) {
{
_.logger.Auto(errorBadConfigData).ArgClass(class); _.logger.Auto(errorBadConfigData).ArgClass(class);
// Fallback to "default" config // Fallback to "default" config
configNameCopy = _.text.FromString(defaultConfigName); configNameCopy = _.text.FromString(defaultConfigName);
configClass.static.NewConfig(configNameCopy); configClass.static.NewConfig(configNameCopy);
newConfig = newConfig = FeatureConfig(configClass.static.GetConfigInstance(configNameCopy));
FeatureConfig(configClass.static.GetConfigInstance(configNameCopy)); } else {
}
else {
configNameCopy = newConfigName.Copy(); configNameCopy = newConfigName.Copy();
} }
SwapConfig(newConfig); SwapConfig(newConfig);
@ -289,12 +285,8 @@ public static final function bool IsEnabled()
public static final function Feature EnableMe(BaseText configName) public static final function Feature EnableMe(BaseText configName)
{ {
local Feature myInstance; local Feature myInstance;
myInstance = GetEnabledInstance();
if (myInstance != none) DisableMe();
{
myInstance.ApplyConfig(configName);
return myInstance;
}
myInstance = Feature(__().memory.Allocate(default.class)); myInstance = Feature(__().memory.Allocate(default.class));
__().environment.EnableFeature(myInstance, configName); __().environment.EnableFeature(myInstance, configName);
return myInstance; return myInstance;
@ -336,8 +328,8 @@ protected function OnEnabled(){}
protected function OnDisabled(){} protected function OnDisabled(){}
/** /**
* Will be called whenever caller `Feature` class must change it's config * Will be called whenever caller `Feature` class must change it's config parameters.
* parameters. This can be done both when the `Feature` is enabled or disabled. * It is guaranteed that `Feature` will be disabled during this call.
* *
* @param newConfigData New config that caller `Feature`'s class must use. * @param newConfigData New config that caller `Feature`'s class must use.
* We pass `FeatureConfig` value for performance and simplicity reasons, * 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 * parse their arguments into standard Acedia collection. It also allows to
* manage them (and specify limitation on how they can be called) in a * manage them (and specify limitation on how they can be called) in a
* centralized manner. * centralized manner.
* Copyright 2021-2022 Anton Tarasenko * Copyright 2021-2023 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
* *
@ -117,6 +117,18 @@ protected function OnEnabled()
commandDelimiters[2] = _.text.FromString("["); commandDelimiters[2] = _.text.FromString("[");
// Negation of the selector // Negation of the selector
commandDelimiters[3] = _.text.FromString("!"); 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() protected function OnDisabled()
@ -150,28 +162,8 @@ protected function SwapConfig(FeatureConfig config)
_.memory.Free(chatCommandPrefix); _.memory.Free(chatCommandPrefix);
chatCommandPrefix = _.text.FromString(newConfig.chatCommandPrefix); chatCommandPrefix = _.text.FromString(newConfig.chatCommandPrefix);
allowedPlayers = newConfig.allowedPlayers; allowedPlayers = newConfig.allowedPlayers;
if (useChatInput != newConfig.useChatInput) useChatInput = newConfig.useChatInput;
{ useMutateInput = newConfig.useMutateInput;
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();
}
}
} }
/** /**

21
sources/Users/Users_Feature.uc

@ -80,7 +80,13 @@ protected function OnEnabled()
feature.RegisterCommand(class'ACommandUserGroups'); feature.RegisterCommand(class'ACommandUserGroups');
feature.FreeSelf(); feature.FreeSelf();
} }
LoadUserData(); if (_server.IsAvailable()) {
LoadUserData();
SetupPersistentData(usePersistentData);
} else {
_.logger.Auto(errNoServerCore);
return;
}
} }
protected function OnDisabled() protected function OnDisabled()
@ -113,17 +119,6 @@ protected function SwapConfig(FeatureConfig config)
useDatabaseForGroupsData = newConfig.useDatabaseForGroupsData; useDatabaseForGroupsData = newConfig.useDatabaseForGroupsData;
groupsDatabaseLink = newConfig.groupsDatabaseLink; groupsDatabaseLink = newConfig.groupsDatabaseLink;
availableUserGroups = newConfig.localUserGroup; 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.") 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.") 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.") 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.") 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