Browse Source

Change feature command to use announcer

feature_improvement
Anton Tarasenko 2 years ago
parent
commit
62ea3e50e6
  1. 43
      sources/CommandAnnouncer.uc
  2. 221
      sources/Commands/ACommandFeature.uc
  3. 224
      sources/Commands/ACommandFeature_Announcer.uc

43
sources/CommandAnnouncer.uc

@ -129,22 +129,24 @@ public final function Setup(
ConsoleWriter newPublicConsole) ConsoleWriter newPublicConsole)
{ {
target = none; target = none;
_.memory.Free(targetName);
targetName = none;
if (newTarget != none && newTarget.IsAllocated()) if (newTarget != none && newTarget.IsAllocated())
{ {
target = newTarget; target = newTarget;
targetLifeVersion = newTarget.GetLifeVersion(); targetLifeVersion = newTarget.GetLifeVersion();
_.memory.Free(targetName);
targetName = target targetName = target
.GetName() .GetName()
.IntoMutableText() .IntoMutableText()
.ChangeDefaultColor(_.color.Gray); .ChangeDefaultColor(_.color.Gray);
} }
instigator = none; instigator = none;
_.memory.Free(instigatorName);
instigatorName = none;
if (newInstigator != none && newInstigator.IsAllocated()) if (newInstigator != none && newInstigator.IsAllocated())
{ {
instigator = newInstigator; instigator = newInstigator;
instigatorLifeVersion = newInstigator.GetLifeVersion(); instigatorLifeVersion = newInstigator.GetLifeVersion();
_.memory.Free(instigatorName);
instigatorName = instigator instigatorName = instigator
.GetName() .GetName()
.IntoMutableText() .IntoMutableText()
@ -168,11 +170,11 @@ protected final function MakeAnnouncement(AnnouncementVariations variations)
local ConsoleWriter instigatorConsole, targetConsole; local ConsoleWriter instigatorConsole, targetConsole;
if (!variations.initialized) return; if (!variations.initialized) return;
if (!AreClassesValid()) return; if (!ValidateClasses()) return;
instigatorConsole = _.console.For(instigator); instigatorConsole = _.console.For(instigator);
targetConsole = _.console.For(target); targetConsole = _.console.For(target);
if (instigator.SameAs(target)) if (target == none || instigator.SameAs(target))
{ {
// If instigator is targeting himself, then there is no need for // If instigator is targeting himself, then there is no need for
// a separate announcement to target // a separate announcement to target
@ -218,24 +220,39 @@ protected final function array<TextTemplate> MakeArray(
{ {
local array<TextTemplate> result; local array<TextTemplate> result;
result[result.length] = variations.toSelfReport; if (variations.toSelfReport != none) {
result[result.length] = variations.toSelfPublic; result[result.length] = variations.toSelfReport;
result[result.length] = variations.toOtherReport; }
result[result.length] = variations.toOtherPrivate; if (variations.toSelfPublic != none) {
result[result.length] = variations.toOtherPublic; result[result.length] = variations.toSelfPublic;
}
if (variations.toOtherReport != none) {
result[result.length] = variations.toOtherReport;
}
if (variations.toOtherPrivate != none) {
result[result.length] = variations.toOtherPrivate;
}
if (variations.toOtherPublic != none) {
result[result.length] = variations.toOtherPublic;
}
return result; return result;
} }
private final function bool AreClassesValid() private final function bool ValidateClasses()
{ {
if (instigator == none) return false; if (instigator == none) return false;
if (target == none) return false;
if (publicConsole == none) return false; if (publicConsole == none) return false;
if (instigator.GetLifeVersion() != instigatorLifeVersion) return false; if (instigator.GetLifeVersion() != instigatorLifeVersion) return false;
if (target.GetLifeVersion() != targetLifeVersion) return false;
if (!instigator.IsExistent()) return false; if (!instigator.IsExistent()) return false;
if (!target.IsExistent()) return false;
if (target != none)
{
if ( target.GetLifeVersion() != targetLifeVersion
|| !target.IsExistent())
{
target = none;
}
}
if (publicConsole.GetLifeVersion() != publicConsoleLifeVersion) { if (publicConsole.GetLifeVersion() != publicConsoleLifeVersion) {
return false; return false;
} }

221
sources/Commands/ACommandFeature.uc

@ -22,6 +22,14 @@ class ACommandFeature extends Command;
// TODO: autoconf, newconf, deleteconf, setconf // TODO: autoconf, newconf, deleteconf, setconf
// TODO: when displaying features - display which one is enabled // TODO: when displaying features - display which one is enabled
var private ACommandFeature_Announcer announcer;
protected function Finalizer()
{
_.memory.Free(announcer);
super.Finalizer();
}
protected function BuildData(CommandDataBuilder builder) protected function BuildData(CommandDataBuilder builder)
{ {
builder.Name(P("feature")).Summary(P("Managing features.")) builder.Name(P("feature")).Summary(P("Managing features."))
@ -34,174 +42,116 @@ protected function BuildData(CommandDataBuilder builder)
builder.SubCommand(P("disable")) builder.SubCommand(P("disable"))
.ParamText(P("feature")) .ParamText(P("feature"))
.Describe(P("Disables specified <feature>.")); .Describe(P("Disables specified <feature>."));
announcer = ACommandFeature_Announcer(
_.memory.Allocate(class'ACommandFeature_Announcer'));
} }
protected function Executed(CallData result, EPlayer callerPlayer) protected function Executed(CallData arguments, EPlayer instigator)
{ {
if (result.subCommandName.IsEmpty()) { announcer.Setup(none, instigator, othersConsole);
if (arguments.subCommandName.IsEmpty()) {
ShowAllFeatures(); ShowAllFeatures();
} }
else if (result.subCommandName.Compare(P("enable"))) else if (arguments.subCommandName.Compare(P("enable")))
{ {
TryEnableFeature( EnableFeature(
callerPlayer, arguments.parameters.GetText(P("feature")),
result.parameters.GetText(P("feature")), arguments.parameters.GetText(P("config")));
result.parameters.GetText(P("config")));
} }
else if (result.subCommandName.Compare(P("disable"))) { else if (arguments.subCommandName.Compare(P("disable"))) {
DisableFeature(callerPlayer, result.parameters.GetText(P("feature"))); DisableFeature(arguments.parameters.GetText(P("feature")));
} }
} }
protected function TryEnableFeature( protected function EnableFeature(BaseText featureName, BaseText configParameter)
EPlayer callerPlayer,
BaseText featureName,
BaseText chosenConfig)
{ {
local Text oldConfig, newConfig; local bool wasEnabled;
local class<Feature> featureClass; local Text oldConfig, newConfig;
local class<FeatureConfig> configClass; local Feature instance;
featureClass = LoadFeatureClass(featureName); local class<Feature> featureClass;
if (featureClass == none) return;
configClass = featureClass.default.configClass;
if (configClass == none) return;
if (chosenConfig == none) { featureClass = LoadFeatureClass(featureName);
newConfig = configClass.static.GetAutoEnabledConfig(); if (featureClass == none) {
}
else if (!configClass.static.Exists(chosenConfig))
{
callerConsole
.Write(P("Specified config \""))
.Write(chosenConfig)
.WriteLine(F("\" {$TextFailure doesn't exist}"));
return;
}
else {
newConfig = chosenConfig.Copy();
}
if (newConfig == none)
{
callerConsole
.Write(F("{$TextFailue No config specified} and"
@ "{$TextFailure no auto-enabled config} exists for feature "))
.UseColorOnce(_.color.TextEmphasis)
.WriteLine(newConfig);
_.memory.Free(newConfig);
return; return;
} }
wasEnabled = featureClass.static.IsEnabled();
oldConfig = featureClass.static.GetCurrentConfig(); oldConfig = featureClass.static.GetCurrentConfig();
if (oldConfig != none && oldConfig.Compare(chosenConfig, SCASE_INSENSITIVE)) newConfig = GetConfigFromParameter(configParameter, featureClass);
// Already enabled with the same config!
if (oldConfig != none && oldConfig.Compare(newConfig, SCASE_INSENSITIVE))
{ {
callerConsole announcer.AnnounceFailedAlreadyEnabled(featureClass, newConfig);
.Write(P("Config "))
.Write(chosenConfig)
.WriteLine(P(" is already enabled"));
_.memory.Free(oldConfig);
_.memory.Free(newConfig); _.memory.Free(newConfig);
_.memory.Free(oldConfig);
return; return;
} }
EnableFeature( // Try enabling and report the result
callerPlayer, instance = featureClass.static.EnableMe(newConfig);
featureClass, if (instance == none) {
configClass, announcer.AnnounceFailedCannotEnableFeature(featureClass, newConfig);
newConfig, }
chosenConfig == none); else if (wasEnabled) {
announcer.AnnounceSwappedConfig(featureClass, oldConfig, newConfig);
}
else {
announcer.AnnounceEnabledFeature(featureClass, newConfig);
}
_.memory.Free(newConfig); _.memory.Free(newConfig);
_.memory.Free(oldConfig); _.memory.Free(oldConfig);
} }
protected function EnableFeature( protected function DisableFeature(Text featureName)
EPlayer callerPlayer,
class<Feature> featureClass,
class<FeatureConfig> configClass,
BaseText chosenConfig,
bool autoConfig)
{ {
local bool wasEnabled; local class<Feature> featureClass;
local Feature instance;
local Text featureName, callerName;
if (callerPlayer == none) return;
if (featureClass == none) return;
if (configClass == none) return;
callerName = callerPlayer.GetName(); featureClass = LoadFeatureClass(featureName);
featureName = _.text.FromClass(featureClass); if (featureClass == none) {
wasEnabled = featureClass.static.IsEnabled(); return;
instance = featureClass.static.EnableMe(chosenConfig);
if (instance == none)
{
callerConsole.Write(F("Something went {$TextFailure wrong},"
@ "{$TextFailure failed} to enabled feature"))
.UseColorOnce(_.color.TextEmphasis).WriteLine(featureName);
} }
else if (wasEnabled) if (!featureClass.static.IsEnabled())
{ {
callerConsole announcer.AnnounceFailedAlreadyDisabled(featureClass);
.Write(P("Swapping config for the feature ")) return;
.UseColorOnce(_.color.TextEmphasis).Write(featureName)
.Write(P(" to \"")).Write(chosenConfig).WriteLine(P("\""));
othersConsole
.Write(callerName)
.Write(P(" swapped config for the feature "))
.UseColorOnce(_.color.TextEmphasis).Write(featureName)
.Write(P(" to \"")).Write(chosenConfig).WriteLine(P("\""));
} }
else featureClass.static.DisableMe();
{ // It is possible that this command itself is destroyed after above command
callerConsole // so do the check just in case
.Write(P("Enabling feature ")) if (IsAllocated()) {
.UseColorOnce(_.color.TextEmphasis).Write(featureName) announcer.AnnounceDisabledFeature(featureClass);
.Write(P(" with config \"")).Write(chosenConfig).WriteLine(P("\""));
othersConsole
.Write(callerName)
.Write(P(" enabled feature "))
.UseColorOnce(_.color.TextEmphasis).Write(featureName)
.Write(P(" with config \"")).Write(chosenConfig).WriteLine(P("\""));
} }
_.memory.Free(callerName);
_.memory.Free(featureName);
} }
protected function DisableFeature(EPlayer callerPlayer, Text featureName) protected function Text GetConfigFromParameter(
BaseText configParameter,
class<Feature> featureClass)
{ {
local Text playerName; local Text resolvedConfig;
local Text featureRealName; local class<FeatureConfig> configClass;
local class<Feature> featureClass;
featureClass = LoadFeatureClass(featureName);
if (featureClass == none) return;
if (callerPlayer == none) return;
featureRealName = _.text.FromClass(featureClass); if (featureClass == none) {
playerName = callerPlayer.GetName(); return none;
if (!featureClass.static.IsEnabled()) }
configClass = featureClass.default.configClass;
if (configClass == none)
{ {
callerConsole announcer.AnnounceFailedNoConfigClass(featureClass);
.Write(P("Feature ")) return none;
.UseColorOnce(_.color.TextEmphasis).Write(featureRealName)
.WriteLine(F(" is already {$TextNegative disabled}"));
_.memory.Free(featureRealName);
_.memory.Free(playerName);
return;
} }
featureClass.static.DisableMe(); // If config was specified - simply check that it exists
// It is possible that this command itself is destroyed after above command if (configParameter != none)
// so do the check just in case
if (IsAllocated())
{ {
callerConsole if (configClass.static.Exists(configParameter)) {
.Write(P("Feature ")) return configParameter.Copy();
.UseColorOnce(_.color.TextEmphasis).Write(featureRealName) }
.WriteLine(F(" is {$TextNegative disabled}")); announcer.AnnounceFailedConfigMissing(configParameter);
othersConsole return none;
.Write(playerName)
.Write(F(" {$TextNegative disabled} feature "))
.UseColorOnce(_.color.TextEmphasis).WriteLine(featureRealName);
} }
// `_` might be gone here // If it wasn't specified - try auto config instead
__().memory.Free(featureRealName); resolvedConfig = configClass.static.GetAutoEnabledConfig();
__().memory.Free(playerName); if (resolvedConfig == none) {
announcer.AnnounceFailedNoConfigProvided(featureClass);
}
return resolvedConfig;
} }
protected function class<Feature> LoadFeatureClass(BaseText featureName) protected function class<Feature> LoadFeatureClass(BaseText featureName)
@ -218,12 +168,8 @@ protected function class<Feature> LoadFeatureClass(BaseText featureName)
featureClassName = featureName.Copy(); featureClassName = featureName.Copy();
} }
featureClass = class<Feature>(_.memory.LoadClass(featureClassName)); featureClass = class<Feature>(_.memory.LoadClass(featureClassName));
if (featureClass == none) if (featureClass == none) {
{ announcer.AnnounceFailedToLoadFeatureClass(featureName);
callerConsole
.Write(F("{$TextFailure Failed} to load feature `"))
.Write(featureName)
.WriteLine(P("`"));
} }
_.memory.Free(featureClassName); _.memory.Free(featureClassName);
return featureClass; return featureClass;
@ -247,6 +193,7 @@ protected function ShowFeature(class<Feature> feature)
local ReportTool reportTool; local ReportTool reportTool;
local array<Text> availableConfigs; local array<Text> availableConfigs;
local class<FeatureConfig> configClass; local class<FeatureConfig> configClass;
if (feature == none) { if (feature == none) {
return; return;
} }

224
sources/Commands/ACommandFeature_Announcer.uc

@ -0,0 +1,224 @@
/**
* Announcer for `ACommandFeature`.
* Copyright 2022 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
*
* Acedia is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License, or
* (at your option) any later version.
*
* Acedia is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/
class ACommandFeature_Announcer extends CommandAnnouncer;
var private AnnouncementVariations enabledFeature, disabledFeature;
var private AnnouncementVariations swappedConfig;
var private AnnouncementVariations failedToLoadFeatureClass;
var private AnnouncementVariations failedNoConfigProvided, failedConfigMissing;
var private AnnouncementVariations failedCannotEnableFeature;
var private AnnouncementVariations failedNoConfigClass;
var private AnnouncementVariations failedAlreadyEnabled, failedAlreadyDisabled;
protected function Finalizer()
{
FreeVariations(enabledFeature);
FreeVariations(disabledFeature);
FreeVariations(swappedConfig);
FreeVariations(failedToLoadFeatureClass);
FreeVariations(failedNoConfigProvided);
FreeVariations(failedConfigMissing);
FreeVariations(failedCannotEnableFeature);
FreeVariations(failedNoConfigClass);
FreeVariations(failedAlreadyEnabled);
FreeVariations(failedAlreadyDisabled);
super.Finalizer();
}
public final function AnnounceEnabledFeature(
class<Feature> featureClass,
BaseText configName)
{
local int i;
local array<TextTemplate> templates;
if (!enabledFeature.initialized)
{
enabledFeature.initialized = true;
enabledFeature.toSelfReport = _.text.MakeTemplate_S(
"Feature {$TextEmphasis `%1`} {$TextPositive enabled} with config"
@ "\"%2\"");
enabledFeature.toSelfPublic = _.text.MakeTemplate_S(
"%%instigator%% {$TextPositive enabled} feature"
@ "{$TextEmphasis `%1`} with config \"%2\"");
}
templates = MakeArray(enabledFeature);
for (i = 0; i < templates.length; i += 1) {
templates[i].Reset().ArgClass(featureClass).Arg(configName);
}
MakeAnnouncement(enabledFeature);
}
public final function AnnounceDisabledFeature(class<Feature> featureClass)
{
local int i;
local array<TextTemplate> templates;
if (!disabledFeature.initialized)
{
disabledFeature.initialized = true;
disabledFeature.toSelfReport = _.text.MakeTemplate_S(
"Feature {$TextEmphasis `%1`} {$TextNegative disabled}");
disabledFeature.toSelfPublic = _.text.MakeTemplate_S(
"%%instigator%% {$TextNegative disabled} feature"
@ "{$TextEmphasis `%1`}");
}
templates = MakeArray(disabledFeature);
for (i = 0; i < templates.length; i += 1) {
templates[i].Reset().ArgClass(featureClass);
}
MakeAnnouncement(disabledFeature);
}
public final function AnnounceSwappedConfig(
class<Feature> featureClass,
BaseText oldConfig,
BaseText newConfig)
{
local int i;
local array<TextTemplate> templates;
if (!swappedConfig.initialized)
{
swappedConfig.initialized = true;
swappedConfig.toSelfReport = _.text.MakeTemplate_S(
"Config for feature {$TextEmphasis `%1`} {$TextNeutral swapped}"
@ "from \"%2\" to \"%3\"");
swappedConfig.toSelfPublic = _.text.MakeTemplate_S(
"%%instigator%% {$TextNeutral swapped} config for feature"
@ "{$TextEmphasis `%1`} from \"%2\" to \"%3\"");
}
templates = MakeArray(swappedConfig);
for (i = 0; i < templates.length; i += 1)
{
templates[i]
.Reset()
.ArgClass(featureClass)
.Arg(oldConfig)
.Arg(newConfig);
}
MakeAnnouncement(swappedConfig);
}
public final function AnnounceFailedToLoadFeatureClass(BaseText failedClassName)
{
if (!failedToLoadFeatureClass.initialized)
{
failedToLoadFeatureClass.initialized = true;
failedToLoadFeatureClass.toSelfReport = _.text.MakeTemplate_S(
"{$TextFailure Failed} to load feature class {$TextEmphasis `%1`}");
}
failedToLoadFeatureClass.toSelfReport.Reset().Arg(failedClassName);
MakeAnnouncement(failedToLoadFeatureClass);
}
public final function AnnounceFailedNoConfigProvided(
class<Feature> featureClass)
{
if (!failedNoConfigProvided.initialized)
{
failedNoConfigProvided.initialized = true;
failedNoConfigProvided.toSelfReport = _.text.MakeTemplate_S(
"{$TextFailue No config specified} and {$TextFailure no"
@ "auto-enabled config} exists for feature {$TextEmphasis `%1`}");
}
failedNoConfigProvided.toSelfReport.Reset().ArgClass(featureClass);
MakeAnnouncement(failedNoConfigProvided);
}
public final function AnnounceFailedConfigMissing(BaseText config)
{
if (!failedConfigMissing.initialized)
{
failedConfigMissing.initialized = true;
failedConfigMissing.toSelfReport = _.text.MakeTemplate_S(
"Specified config \"%1\" {$TextFailue doesn't exist}");
}
failedConfigMissing.toSelfReport.Reset().Arg(config);
MakeAnnouncement(failedConfigMissing);
}
public final function AnnounceFailedCannotEnableFeature(
class<Feature> featureClass,
BaseText config)
{
if (!failedCannotEnableFeature.initialized)
{
failedCannotEnableFeature.initialized = true;
failedCannotEnableFeature.toSelfReport = _.text.MakeTemplate_S(
"Something went {$TextFailure wrong}, {$TextFailure failed} to"
@ "enable feature {$TextEmphasis `%1`} with config \"%2\"");
}
failedCannotEnableFeature.toSelfReport
.Reset()
.ArgClass(featureClass)
.Arg(config);
MakeAnnouncement(failedCannotEnableFeature);
}
public final function AnnounceFailedNoConfigClass(
class<Feature> featureClass)
{
if (!failedNoConfigClass.initialized)
{
failedNoConfigClass.initialized = true;
failedNoConfigClass.toSelfReport = _.text.MakeTemplate_S(
"Feature {$TextEmphasis `%1`} {$TextFailure does not have config"
@ "class}! This is most likely caused by its faulty"
@ "implementation");
}
failedNoConfigClass.toSelfReport.Reset().ArgClass(featureClass);
MakeAnnouncement(failedNoConfigClass);
}
public final function AnnounceFailedAlreadyDisabled(
class<Feature> featureClass)
{
if (!failedAlreadyDisabled.initialized)
{
failedAlreadyDisabled.initialized = true;
failedAlreadyDisabled.toSelfReport = _.text.MakeTemplate_S(
"Feature {$TextEmphasis `%1`} is already {$TextNegative disabled}");
}
failedAlreadyDisabled.toSelfReport.Reset().ArgClass(featureClass);
MakeAnnouncement(failedAlreadyDisabled);
}
public final function AnnounceFailedAlreadyEnabled(
class<Feature> featureClass,
BaseText config)
{
if (!failedAlreadyEnabled.initialized)
{
failedAlreadyEnabled.initialized = true;
failedAlreadyEnabled.toSelfReport = _.text.MakeTemplate_S(
"Feature {$TextEmphasis `%1`} is already {$TextNegative enabled}"
@ "with specified config \"%2\"");
}
failedAlreadyEnabled.toSelfReport
.Reset()
.ArgClass(featureClass)
.Arg(config);
MakeAnnouncement(failedAlreadyEnabled);
}
defaultproperties
{
}
Loading…
Cancel
Save