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. 39
      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 /// 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 /// (either "weapon", "color", "feature", "entity" or some kind of custom alias source name) will
/// make values prefixed with "$" to be resolved as custom aliases. /// 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( public final function ParamText(
BaseText name, BaseText name,
optional BaseText variableName, 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 /// 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 /// (either "weapon", "color", "feature", "entity" or some kind of custom alias source name) will
/// make values prefixed with "$" to be resolved as custom aliases. /// 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( public final function ParamTextList(
BaseText name, BaseText name,
optional BaseText variableName, optional BaseText variableName,

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

@ -619,6 +619,7 @@ private final function bool ParseTextValue(
local bool failedParsing; local bool failedParsing;
local MutableText textValue; local MutableText textValue;
local Parser.ParserState initialState; local Parser.ParserState initialState;
local HashTable resolvedPair;
// (needs some work for reading formatting `string`s from `Text` objects) // (needs some work for reading formatting `string`s from `Text` objects)
initialState = commandParser.Skip().GetCurrentState(); initialState = commandParser.Skip().GetCurrentState();
@ -639,24 +640,35 @@ private final function bool ParseTextValue(
commandParser.Fail(); commandParser.Fail();
return false; return false;
} }
AutoResolveAlias(textValue, expectedParameter.aliasSourceName); resolvedPair = AutoResolveAlias(textValue, expectedParameter.aliasSourceName);
if (resolvedPair != none) {
RecordParameter(parsedParameters, expectedParameter, resolvedPair);
_.memory.Free(textValue);
} else {
RecordParameter(parsedParameters, expectedParameter, textValue.IntoText()); RecordParameter(parsedParameters, expectedParameter, textValue.IntoText());
}
return true; return true;
} }
// Resolves alias with appropriate source, if parameter was specified to be // Resolves alias and returns it, along with the resolved value, if parameter was specified to be
// auto-resolved. // auto-resolved.
// Resolved values is returned through first out-parameter. // Returns `none` otherwise.
private final function AutoResolveAlias( private final function HashTable AutoResolveAlias(MutableText textValue, Text aliasSourceName) {
out MutableText textValue, local HashTable result;
Text aliasSourceName) local Text resolvedValue, immutableValue;
{
local Text resolvedValue;
if (textValue == none) return; if (textValue == none) return none;
if (aliasSourceName == none) return; if (aliasSourceName == none) return none;
if (!textValue.StartsWithS("$")) return;
// 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"))) { if (aliasSourceName.Compare(P("weapon"))) {
resolvedValue = _.alias.ResolveWeapon(textValue, true); resolvedValue = _.alias.ResolveWeapon(textValue, true);
} }
@ -672,8 +684,9 @@ private final function AutoResolveAlias(
else { else {
resolvedValue = _.alias.ResolveCustom(aliasSourceName, textValue, true); resolvedValue = _.alias.ResolveCustom(aliasSourceName, textValue, true);
} }
textValue.FreeSelf(); result.SetItem(P("value"), resolvedValue);
textValue = resolvedValue.IntoMutableText(); _.memory.Free2(resolvedValue, immutableValue);
return result;
} }
// Assumes `commandParser` and `parsedParameters` are not `none`. // Assumes `commandParser` and `parsedParameters` are not `none`.

Loading…
Cancel
Save