/**
* Author: dkanus
* Home repo: https://www.insultplayers.ru/git/AcediaFramework/AcediaCore
* License: GPL
* Copyright 2023 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 .
*/
class CommandsTool extends CmdItemsTool;
//! This is a base class for auxiliary objects that will be used for storing
//! named [`Command`] instances.
//!
//! This storage class allows for efficient manipulation and retrieval of
//! [`Command`]s, along with information about what use groups were authorized
//! to use them.
//!
//! Additionally, this tool allows for efficient fetching of commands that
//! belong to a particular *command group*.
/// [`HashTable`] that maps a command group name to a set of command names that
/// belong to it.
var private HashTable groupedCommands;
protected function Constructor() {
super.Constructor();
groupedCommands = _.collections.EmptyHashTable();
}
protected function Finalizer() {
super.Finalizer();
_.memory.Free(groupedCommands);
groupedCommands = none;
}
/// Returns all known command groups' names.
public final function array GetGroupsNames() {
local array emptyResult;
if (groupedCommands != none) {
return groupedCommands.GetTextKeys();
}
return emptyResult;
}
/// Returns array of names of all available commands belonging to the specified
/// group.
public final function array GetCommandNamesInGroup(BaseText groupName) {
local int i;
local ArrayList commandNamesArray;
local array result;
if (groupedCommands == none) return result;
commandNamesArray = groupedCommands.GetArrayList(groupName);
if (commandNamesArray == none) return result;
for (i = 0; i < commandNamesArray.GetLength(); i += 1) {
result[result.length] = commandNamesArray.GetText(i);
}
_.memory.Free(commandNamesArray);
return result;
}
protected function ItemCard MakeCard(class commandClass, BaseText itemName) {
local Command newCommandInstance;
local ItemCard newCard;
local Text commandGroup;
if (class(commandClass) != none) {
newCommandInstance = Command(_.memory.Allocate(commandClass, true));
newCommandInstance.Initialize(itemName);
newCard = ItemCard(_.memory.Allocate(class'ItemCard'));
newCard.InitializeWithInstance(newCommandInstance);
// Guaranteed to be lower case (keys of [`HashTable`])
if (itemName != none) {
itemName = itemName.LowerCopy();
} else {
itemName = newCommandInstance.GetPreferredName();
}
commandGroup = newCommandInstance.GetGroupName();
AssociateGroupAndName(commandGroup, itemName);
_.memory.Free3(newCommandInstance, itemName, commandGroup);
}
return newCard;
}
protected function DiscardCard(ItemCard toDiscard) {
local Text groupKey, commandName;
local Command storedCommand;
local ArrayList listOfCommands;
if (toDiscard == none) return;
// Guaranteed to store a [`Command`]
storedCommand = Command(toDiscard.GetItem());
if (storedCommand == none) return;
// Guaranteed to be stored in a lower case
commandName = storedCommand.GetName();
listOfCommands = groupedCommands.GetArrayList(groupKey);
if (listOfCommands != none && commandName != none) {
listOfCommands.RemoveItem(commandName);
}
_.memory.Free2(commandName, storedCommand);
}
// Expect both arguments to be not `none`.
// Expect both arguments to be lower-case.
private final function AssociateGroupAndName(BaseText groupKey, BaseText commandName) {
local ArrayList listOfCommands;
if (groupedCommands != none) {
listOfCommands = groupedCommands.GetArrayList(groupKey);
if (listOfCommands == none) {
listOfCommands = _.collections.EmptyArrayList();
}
if (listOfCommands.Find(commandName) < 0) {
// `< 0` means not found
listOfCommands.AddItem(commandName);
}
// Set `listOfCommands` in case we've just created that array.
// Won't do anything if it is already recorded there.
groupedCommands.SetItem(groupKey, listOfCommands);
}
}
defaultproperties {
ruleBaseClass = class'Command';
}