177 lines
6.7 KiB
Ucode
177 lines
6.7 KiB
Ucode
/**
|
|
* 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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
class ItemCard extends AcediaObject;
|
|
|
|
//! Utility class designed for storing either class of an object
|
|
//! (possibly also a specific instance) along with authorization information:
|
|
//! which user groups are allowed to use stored entity and with what level of
|
|
//! permissions (defined by the name of a config with permissions).
|
|
//!
|
|
//! [`ItemCard`] has to be initialized with either [`InitializeWithClass()`] or
|
|
//! [`InitializeWithInstance()`] before it can be used.
|
|
|
|
/// Class of object that this card describes.
|
|
var private class<AcediaObject> storedClass;
|
|
/// Instance of an object (can also *optionally* be stored in this card)
|
|
var private AcediaObject storedInstance;
|
|
|
|
/// This [`HashTable`] maps authorized groups to their respective config names.
|
|
///
|
|
/// Each key represents an authorized group, and its corresponding value
|
|
/// indicates the associated config name. If a key has a value of `none`,
|
|
/// the default config (named "default") should be used for that group.
|
|
var private HashTable groupToConfig;
|
|
|
|
var LoggerAPI.Definition errGroupAlreadyHasConfig;
|
|
|
|
protected function Finalizer() {
|
|
_.memory.Free2(storedInstance, groupToConfig);
|
|
storedInstance = none;
|
|
storedClass = none;
|
|
groupToConfig = none;
|
|
}
|
|
|
|
/// Initializes the caller [`ItemCard`] object with class to be stored.
|
|
///
|
|
/// Initialization can only be done once: once method returned `true`,
|
|
/// all future calls will fail.
|
|
///
|
|
/// Returns `false` if caller was already initialized or `none` is provided as
|
|
/// an argument. Otherwise succeeds and returns `true`.
|
|
public function bool InitializeWithClass(class<AcediaObject> toStore) {
|
|
if (storedClass != none) return false;
|
|
if (toStore == none) return false;
|
|
|
|
storedClass = toStore;
|
|
groupToConfig = _.collections.EmptyHashTable();
|
|
return true;
|
|
}
|
|
|
|
/// Initializes the caller [`ItemCard`] object with an object to be stored.
|
|
///
|
|
/// Initialization can only be done once: once method returned `true`,
|
|
/// all future calls will fail.
|
|
///
|
|
/// Returns `false` caller was already initialized or `none` is provided as
|
|
/// an argument. Otherwise succeeds and returns `true`.
|
|
public function bool InitializeWithInstance(AcediaObject toStore) {
|
|
if (storedClass != none) return false;
|
|
if (toStore == none) return false;
|
|
|
|
storedClass = toStore.class;
|
|
storedInstance = toStore;
|
|
storedInstance.NewRef();
|
|
groupToConfig = _.collections.EmptyHashTable();
|
|
return true;
|
|
}
|
|
|
|
/// Authorizes a new group to use the this card's item.
|
|
///
|
|
/// This function allows to specify the config name for a particular user group.
|
|
/// If this config name is skipped (specified as `none`), then "default" will be
|
|
/// used instead.
|
|
///
|
|
/// Function will return `true` if group was successfully authorized and
|
|
/// `false` otherwise (either group already authorized or caller [`ItemCard`]
|
|
/// isn't initialized).
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// If specified group was already authorized to use card's item, then it
|
|
/// will log an error message about it.
|
|
public function bool AuthorizeGroupWithConfig(BaseText groupName, optional BaseText configName) {
|
|
local Text itemKey;
|
|
local Text storedConfigName;
|
|
|
|
if (storedClass == none) return false;
|
|
if (groupToConfig == none) return false;
|
|
if (groupName == none) return false;
|
|
if (groupName.IsEmpty()) return false;
|
|
|
|
/// Make group name immutable and have its characters have a uniform case to
|
|
/// be usable as case-insensitive keys for [`HashTable`].
|
|
itemKey = groupName.LowerCopy();
|
|
storedConfigName = groupToConfig.GetText(itemKey);
|
|
if (storedConfigName != none) {
|
|
_.logger.Auto(errGroupAlreadyHasConfig)
|
|
.ArgClass(storedClass)
|
|
.Arg(groupName.Copy())
|
|
.Arg(storedConfigName)
|
|
.Arg(configName.Copy());
|
|
_.memory.Free(itemKey);
|
|
return false;
|
|
}
|
|
// We don't actually record "default" value at this point, instead opting
|
|
// to return "default" in getter functions in case stored `configName`
|
|
// is `none`.
|
|
groupToConfig.SetItem(itemKey, configName);
|
|
_.memory.Free(itemKey);
|
|
return true;
|
|
}
|
|
|
|
/// Returns item instance for the caller [`ItemCard`].
|
|
///
|
|
/// Returns `none` iff this card wasn't initialized with an instance.
|
|
public function AcediaObject GetItem() {
|
|
if (storedInstance != none) {
|
|
storedInstance.NewRef();
|
|
}
|
|
return storedInstance;
|
|
}
|
|
|
|
/// Returns item class for the caller [`ItemCard`].
|
|
///
|
|
/// Returns `none` iff this card wasn't initialized.
|
|
public function class<AcediaObject> GetItemClass() {
|
|
return storedClass;
|
|
}
|
|
|
|
/// Returns the name of config that was authorized for the specified group.
|
|
///
|
|
/// Returns `none` if group wasn't authorized, otherwise guaranteed to
|
|
/// return non-`none` and non-empty `Text` value.
|
|
public function Text GetConfigNameForGroup(BaseText groupName) {
|
|
local Text groupNameAsKey, result;
|
|
|
|
if (storedClass == none) return none;
|
|
if (groupToConfig == none) return none;
|
|
if (groupName == none) return none;
|
|
|
|
/// Make group name immutable and have its characters a uniform case to
|
|
/// be usable as case-insensitive keys for [`HashTable`]
|
|
groupNameAsKey = groupName.LowerCopy();
|
|
if (groupToConfig.HasKey(groupNameAsKey)) {
|
|
result = groupToConfig.GetText(groupNameAsKey);
|
|
if (result == none) {
|
|
// If we do have specified group recorded as a key, then we must
|
|
// return non-`none` config name, defaulting to "default" value
|
|
// if none was provided
|
|
result = P("default").Copy();
|
|
}
|
|
}
|
|
_.memory.Free(groupNameAsKey);
|
|
return result;
|
|
}
|
|
|
|
defaultproperties {
|
|
errGroupAlreadyHasConfig = (l=LOG_Error,m="Item `%1` is already added to group '%2' with config '%3'. Attempt to add it with config '%4' is ignored.")
|
|
} |