Browse Source

Change auto-alias resolving in commands to be useful

Previously auto-resolved aliases overwrote user-provided value,
which made it difficult to print response/error messages as a result
of a command, rendering auto-resolving unusable.

This patch fixes that problem by recording both alias and resolved
value inside a `HashTable` value.
pull/12/head
Anton Tarasenko 2 years ago
parent
commit
06915cbddf
  1. 8
      sources/LevelAPI/Features/Commands/CommandDataBuilder.uc
  2. 49
      sources/LevelAPI/Features/Commands/CommandParser.uc

8
sources/LevelAPI/Features/Commands/CommandDataBuilder.uc

@ -637,6 +637,10 @@ public final function ParamNumberList(BaseText name, optional BaseText variableN
/// parameter's value. `none` means that parameter will be recorded as-is, any other value
/// (either "weapon", "color", "feature", "entity" or some kind of custom alias source name) will
/// make values prefixed with "$" to be resolved as custom aliases.
/// In case auto-resolving is used, value will be recorded as a `HasTable` with two fields:
/// "alias" - value provided by user and (in case "$" prefix was used) "value" - actual resolved
/// value of an alias.
/// If alias has failed to be resolved, `none` will be stored as a value.
public final function ParamText(
BaseText name,
optional BaseText variableName,
@ -672,6 +676,10 @@ public final function ParamText(
/// parameter's value. `none` means that parameter will be recorded as-is, any other value
/// (either "weapon", "color", "feature", "entity" or some kind of custom alias source name) will
/// make values prefixed with "$" to be resolved as custom aliases.
/// In case auto-resolving is used, value will be recorded as a `HasTable` with two fields:
/// "alias" - value provided by user and (in case "$" prefix was used) "value" - actual resolved
/// value of an alias.
/// If alias has failed to be resolved, `none` will be stored as a value.
public final function ParamTextList(
BaseText name,
optional BaseText variableName,

49
sources/LevelAPI/Features/Commands/CommandParser.uc

@ -616,9 +616,10 @@ private final function bool ParseTextValue(
HashTable parsedParameters,
Command.Parameter expectedParameter)
{
local bool failedParsing;
local MutableText textValue;
local Parser.ParserState initialState;
local bool failedParsing;
local MutableText textValue;
local Parser.ParserState initialState;
local HashTable resolvedPair;
// (needs some work for reading formatting `string`s from `Text` objects)
initialState = commandParser.Skip().GetCurrentState();
@ -639,24 +640,35 @@ private final function bool ParseTextValue(
commandParser.Fail();
return false;
}
AutoResolveAlias(textValue, expectedParameter.aliasSourceName);
RecordParameter(parsedParameters, expectedParameter, textValue.IntoText());
resolvedPair = AutoResolveAlias(textValue, expectedParameter.aliasSourceName);
if (resolvedPair != none) {
RecordParameter(parsedParameters, expectedParameter, resolvedPair);
_.memory.Free(textValue);
} else {
RecordParameter(parsedParameters, expectedParameter, textValue.IntoText());
}
return true;
}
// Resolves alias with appropriate source, if parameter was specified to be
// auto-resolved.
// Resolved values is returned through first out-parameter.
private final function AutoResolveAlias(
out MutableText textValue,
Text aliasSourceName)
{
local Text resolvedValue;
// Resolves alias and returns it, along with the resolved value, if parameter was specified to be
// auto-resolved.
// Returns `none` otherwise.
private final function HashTable AutoResolveAlias(MutableText textValue, Text aliasSourceName) {
local HashTable result;
local Text resolvedValue, immutableValue;
if (textValue == none) return;
if (aliasSourceName == none) return;
if (!textValue.StartsWithS("$")) return;
if (textValue == none) return none;
if (aliasSourceName == none) return none;
// Always create `HashTable` with at least "alias" key
result = _.collections.EmptyHashTable();
immutableValue = textValue.Copy();
result.SetItem(P("alias"), immutableValue);
_.memory.Free(immutableValue);
// Add "value" key only after we've checked for "$" prefix
if (!textValue.StartsWithS("$")) {
return result;
}
if (aliasSourceName.Compare(P("weapon"))) {
resolvedValue = _.alias.ResolveWeapon(textValue, true);
}
@ -672,8 +684,9 @@ private final function AutoResolveAlias(
else {
resolvedValue = _.alias.ResolveCustom(aliasSourceName, textValue, true);
}
textValue.FreeSelf();
textValue = resolvedValue.IntoMutableText();
result.SetItem(P("value"), resolvedValue);
_.memory.Free2(resolvedValue, immutableValue);
return result;
}
// Assumes `commandParser` and `parsedParameters` are not `none`.

Loading…
Cancel
Save