Browse Source
Change base class for JSON objects from `Object` to `AcediaObject`. Rename some classes/functions/structures/variables to be more compact and/or better convey their meaning. Add appropriate API that contains constructors for JSON objects.new
Anton Tarasenko
5 years ago
7 changed files with 494 additions and 442 deletions
@ -0,0 +1,265 @@ |
|||||||
|
/** |
||||||
|
* This class implements JSON object storage capabilities. |
||||||
|
* Whenever one wants to store JSON data, they need to define such object. |
||||||
|
* It stores name-value pairs, where names are strings and values can be: |
||||||
|
* ~ Boolean, string, null or number (float in this implementation) data; |
||||||
|
* ~ Other JSON objects; |
||||||
|
* ~ JSON Arrays (see `JArray` class). |
||||||
|
* |
||||||
|
* This implementation provides getters and setters for boolean, string, |
||||||
|
* null or number types that allow to freely set and fetch their values |
||||||
|
* by name. |
||||||
|
* JSON objects and arrays can be fetched by getters, but you cannot |
||||||
|
* add existing object or array to another object. Instead one has to create |
||||||
|
* a new, empty object with a certain name and then fill it with data. |
||||||
|
* This allows to avoid loop situations, where object is contained in itself. |
||||||
|
* Functions to remove existing values are also provided and are applicable |
||||||
|
* to all variable types. |
||||||
|
* Setters can also be used to overwrite any value by a different value, |
||||||
|
* even of a different type. |
||||||
|
* Copyright 2020 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 JObject extends JSON; |
||||||
|
|
||||||
|
// We will store all our properties as a simple array of name-value pairs. |
||||||
|
struct JProperty |
||||||
|
{ |
||||||
|
var string name; |
||||||
|
var JStorageAtom value; |
||||||
|
}; |
||||||
|
var private array<JProperty> properties; |
||||||
|
|
||||||
|
// Returns index of name-value pair in `properties` for a given name. |
||||||
|
// Returns `-1` if such a pair does not exist. |
||||||
|
private final function int GetPropertyIndex(string name) |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
for (i = 0; i < properties.length; i += 1) |
||||||
|
{ |
||||||
|
if (name == properties[i].name) |
||||||
|
{ |
||||||
|
return i; |
||||||
|
} |
||||||
|
} |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
// Returns `JType` of a variable with a given name in our properties. |
||||||
|
// This function can be used to check if certain variable exists |
||||||
|
// in this object, since if such variable does not exist - |
||||||
|
// function will return `JSON_Undefined`. |
||||||
|
public final function JType GetTypeOf(string name) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) return JSON_Undefined; |
||||||
|
|
||||||
|
return properties[index].value.type; |
||||||
|
} |
||||||
|
|
||||||
|
// Following functions are getters for various types of variables. |
||||||
|
// Getter for null value simply checks if it's null |
||||||
|
// and returns true/false as a result. |
||||||
|
// Getters for simple types (number, string, boolean) can have optional |
||||||
|
// default value specified, that will be returned if requested variable |
||||||
|
// doesn't exist or has a different type. |
||||||
|
// Getters for object and array types don't take default values and |
||||||
|
// will simply return `none`. |
||||||
|
public final function float GetNumber(string name, optional float defaultValue) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) return defaultValue; |
||||||
|
if (properties[index].value.type != JSON_Number) return defaultValue; |
||||||
|
|
||||||
|
return properties[index].value.numberValue; |
||||||
|
} |
||||||
|
|
||||||
|
public final function string GetString |
||||||
|
( |
||||||
|
string name, |
||||||
|
optional string defaultValue |
||||||
|
) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) return defaultValue; |
||||||
|
if (properties[index].value.type != JSON_String) return defaultValue; |
||||||
|
|
||||||
|
return properties[index].value.stringValue; |
||||||
|
} |
||||||
|
|
||||||
|
public final function bool GetBoolean(string name, optional bool defaultValue) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) return defaultValue; |
||||||
|
if (properties[index].value.type != JSON_Boolean) return defaultValue; |
||||||
|
|
||||||
|
return properties[index].value.booleanValue; |
||||||
|
} |
||||||
|
|
||||||
|
public final function bool IsNull(string name) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) return false; |
||||||
|
if (properties[index].value.type != JSON_Null) return false; |
||||||
|
|
||||||
|
return (properties[index].value.type == JSON_Null); |
||||||
|
} |
||||||
|
|
||||||
|
public final function JArray GetArray(string name) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) return none; |
||||||
|
if (properties[index].value.type != JSON_Array) return none; |
||||||
|
|
||||||
|
return JArray(properties[index].value.complexValue); |
||||||
|
} |
||||||
|
|
||||||
|
public final function JObject GetObject(string name) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) return none; |
||||||
|
if (properties[index].value.type != JSON_Object) return none; |
||||||
|
|
||||||
|
return JObject(properties[index].value.complexValue); |
||||||
|
} |
||||||
|
|
||||||
|
// Following functions provide simple setters for boolean, string, number |
||||||
|
// and null values. |
||||||
|
// They return object itself, allowing user to chain calls like this: |
||||||
|
// `object.SetNumber("num1", 1).SetNumber("num2", 2);`. |
||||||
|
public final function JObject SetNumber(string name, float value) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
local JProperty newProperty; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) |
||||||
|
{ |
||||||
|
index = properties.length; |
||||||
|
} |
||||||
|
|
||||||
|
newProperty.name = name; |
||||||
|
newProperty.value.type = JSON_Number; |
||||||
|
newProperty.value.numberValue = value; |
||||||
|
properties[index] = newProperty; |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
public final function JObject SetString(string name, string value) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
local JProperty newProperty; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) |
||||||
|
{ |
||||||
|
index = properties.length; |
||||||
|
} |
||||||
|
newProperty.name = name; |
||||||
|
newProperty.value.type = JSON_String; |
||||||
|
newProperty.value.stringValue = value; |
||||||
|
properties[index] = newProperty; |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
public final function JObject SetBoolean(string name, bool value) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
local JProperty newProperty; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) |
||||||
|
{ |
||||||
|
index = properties.length; |
||||||
|
} |
||||||
|
newProperty.name = name; |
||||||
|
newProperty.value.type = JSON_Boolean; |
||||||
|
newProperty.value.booleanValue = value; |
||||||
|
properties[index] = newProperty; |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
public final function JObject SetNull(string name) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
local JProperty newProperty; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) |
||||||
|
{ |
||||||
|
index = properties.length; |
||||||
|
} |
||||||
|
newProperty.name = name; |
||||||
|
newProperty.value.type = JSON_Null; |
||||||
|
properties[index] = newProperty; |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
// JSON array and object types don't have setters, but instead have |
||||||
|
// functions to create a new, empty array/object under a certain name. |
||||||
|
// They return object itself, allowing user to chain calls like this: |
||||||
|
// `object.CreateObject("folded object").CreateArray("names list");`. |
||||||
|
public final function JObject CreateArray(string name) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
local JProperty newProperty; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) |
||||||
|
{ |
||||||
|
index = properties.length; |
||||||
|
} |
||||||
|
newProperty.name = name; |
||||||
|
newProperty.value.type = JSON_Array; |
||||||
|
newProperty.value.complexValue = _.json.newArray(); |
||||||
|
properties[index] = newProperty; |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
public final function JObject CreateObject(string name) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
local JProperty newProperty; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) |
||||||
|
{ |
||||||
|
index = properties.length; |
||||||
|
} |
||||||
|
newProperty.name = name; |
||||||
|
newProperty.value.type = JSON_Object; |
||||||
|
newProperty.value.complexValue = _.json.newObject(); |
||||||
|
properties[index] = newProperty; |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
// Removes values with a given name. |
||||||
|
// Returns `true` if value was actually removed and `false` if it didn't exist. |
||||||
|
public final function bool RemoveValue(string name) |
||||||
|
{ |
||||||
|
local int index; |
||||||
|
index = GetPropertyIndex(name); |
||||||
|
if (index < 0) return false; |
||||||
|
|
||||||
|
properties.Remove(index, 1); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
defaultproperties |
||||||
|
{ |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
/** |
||||||
|
* Singleton is an auxiliary class, meant to be used as a base for others, |
||||||
|
* that allows for only one instance of it to exist. |
||||||
|
* To make sure your child class properly works, either don't overload |
||||||
|
* 'PreBeginPlay' or make sure to call it's parent's version. |
||||||
|
* Copyright 2019 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 JSONAPI extends Singleton; |
||||||
|
|
||||||
|
public function JObject newObject() |
||||||
|
{ |
||||||
|
local JObject newObject; |
||||||
|
newObject = Spawn(class'JObject'); |
||||||
|
return newObject; |
||||||
|
} |
||||||
|
|
||||||
|
public function JArray newArray() |
||||||
|
{ |
||||||
|
local JArray newArray; |
||||||
|
newArray = Spawn(class'JArray'); |
||||||
|
return newArray; |
||||||
|
} |
||||||
|
|
||||||
|
defaultproperties |
||||||
|
{ |
||||||
|
} |
@ -1,272 +0,0 @@ |
|||||||
/** |
|
||||||
* This class implements JSON object storage capabilities. |
|
||||||
* Whenever one wants to store JSON data, they need to define such object. |
|
||||||
* It stores name-value pairs, where names are strings and values can be: |
|
||||||
* ~ Boolean, string, null or number (float in this implementation) data; |
|
||||||
* ~ Other JSON objects; |
|
||||||
* ~ JSON Arrays (see `JSONArray` class). |
|
||||||
* |
|
||||||
* This implementation provides getters and setters for boolean, string, |
|
||||||
* null or number types that allow to freely set and fetch their values |
|
||||||
* by name. |
|
||||||
* JSON objects and arrays can be fetched by getters, but you cannot |
|
||||||
* add existing object or array to another object. Instead one has to create |
|
||||||
* a new, empty object with a certain name and then fill it with data. |
|
||||||
* This allows to avoid loop situations, where object is contained in itself. |
|
||||||
* Functions to remove existing values are also provided and are applicable |
|
||||||
* to all variable types. |
|
||||||
* Setters can also be used to overwrite any value by a different value, |
|
||||||
* even of a different type. |
|
||||||
* Copyright 2020 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 JSONObject extends JSONBase; |
|
||||||
|
|
||||||
// We will store all our data as a simple array of key(name)-value pairs. |
|
||||||
struct JSONKeyValuePair |
|
||||||
{ |
|
||||||
var string key; |
|
||||||
var JSONStorageValue value; |
|
||||||
}; |
|
||||||
var private array<JSONKeyValuePair> data; |
|
||||||
|
|
||||||
// Returns index of key-value pair in `data` with a given key. |
|
||||||
// Returns `-1` if such a pair does not exist in `data`. |
|
||||||
private final function int GetIndex(string key) |
|
||||||
{ |
|
||||||
local int i; |
|
||||||
for (i = 0; i < data.length; i += 1) |
|
||||||
{ |
|
||||||
if (key == data[i].key) |
|
||||||
{ |
|
||||||
return i; |
|
||||||
} |
|
||||||
} |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
// Returns `JSONType` of a variable with a given key in our data. |
|
||||||
// This function can be used to check if certain variable exists |
|
||||||
// in this object, since if such variable does not exist - |
|
||||||
// function will return `JSON_Undefined`. |
|
||||||
public final function JSONType GetType(string key) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) return JSON_Undefined; |
|
||||||
|
|
||||||
return data[index].value.type; |
|
||||||
} |
|
||||||
|
|
||||||
// Following functions are getters for various types of variables. |
|
||||||
// Getter for null value simply checks if it's null |
|
||||||
// and returns true/false as a result. |
|
||||||
// Getters for simple types (number, string, boolean) can have optional |
|
||||||
// default value specified, that will be returned if requested variable |
|
||||||
// doesn't exist or has a different type. |
|
||||||
// Getters for object and array types don't take default values and |
|
||||||
// will simply return `none`. |
|
||||||
public final function float GetNumber(string key, optional float defaultValue) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) return defaultValue; |
|
||||||
if (data[index].value.type != JSON_Number) return defaultValue; |
|
||||||
|
|
||||||
return data[index].value.numberValue; |
|
||||||
} |
|
||||||
|
|
||||||
public final function string GetString(string key, optional string defaultValue) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) return defaultValue; |
|
||||||
if (data[index].value.type != JSON_String) return defaultValue; |
|
||||||
|
|
||||||
return data[index].value.stringValue; |
|
||||||
} |
|
||||||
|
|
||||||
public final function bool GetBoolean(string key, optional bool defaultValue) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) return defaultValue; |
|
||||||
if (data[index].value.type != JSON_Boolean) return defaultValue; |
|
||||||
|
|
||||||
return data[index].value.booleanValue; |
|
||||||
} |
|
||||||
|
|
||||||
public final function bool IsNull(string key) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) return false; |
|
||||||
if (data[index].value.type != JSON_Null) return false; |
|
||||||
|
|
||||||
return (data[index].value.type == JSON_Null); |
|
||||||
} |
|
||||||
|
|
||||||
public final function JSONArray GetArray(string key) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) return none; |
|
||||||
if (data[index].value.type != JSON_Array) return none; |
|
||||||
|
|
||||||
return JSONArray(data[index].value.complexValue); |
|
||||||
} |
|
||||||
|
|
||||||
public final function JSONObject GetObject(string key) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) return none; |
|
||||||
if (data[index].value.type != JSON_Object) return none; |
|
||||||
|
|
||||||
return JSONObject(data[index].value.complexValue); |
|
||||||
} |
|
||||||
|
|
||||||
// Following functions provide simple setters for boolean, string, number |
|
||||||
// and null values. |
|
||||||
// They return object itself, allowing user to chain calls like this: |
|
||||||
// `object.SetNumber("num1", 1).SetNumber("num2", 2);`. |
|
||||||
public final function JSONObject SetNumber(string key, float value) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
local JSONKeyValuePair newKeyValuePair; |
|
||||||
local JSONStorageValue newStorageValue; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) |
|
||||||
{ |
|
||||||
index = data.length; |
|
||||||
} |
|
||||||
newStorageValue.type = JSON_Number; |
|
||||||
newStorageValue.numberValue = value; |
|
||||||
newKeyValuePair.key = key; |
|
||||||
newKeyValuePair.value = newStorageValue; |
|
||||||
data[index] = newKeyValuePair; |
|
||||||
return self; |
|
||||||
} |
|
||||||
|
|
||||||
public final function JSONObject SetString(string key, string value) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
local JSONKeyValuePair newKeyValuePair; |
|
||||||
local JSONStorageValue newStorageValue; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) |
|
||||||
{ |
|
||||||
index = data.length; |
|
||||||
} |
|
||||||
newStorageValue.type = JSON_String; |
|
||||||
newStorageValue.stringValue = value; |
|
||||||
newKeyValuePair.key = key; |
|
||||||
newKeyValuePair.value = newStorageValue; |
|
||||||
data[index] = newKeyValuePair; |
|
||||||
return self; |
|
||||||
} |
|
||||||
|
|
||||||
public final function JSONObject SetBoolean(string key, bool value) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
local JSONKeyValuePair newKeyValuePair; |
|
||||||
local JSONStorageValue newStorageValue; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) |
|
||||||
{ |
|
||||||
index = data.length; |
|
||||||
} |
|
||||||
newStorageValue.type = JSON_Boolean; |
|
||||||
newStorageValue.booleanValue = value; |
|
||||||
newKeyValuePair.key = key; |
|
||||||
newKeyValuePair.value = newStorageValue; |
|
||||||
data[index] = newKeyValuePair; |
|
||||||
return self; |
|
||||||
} |
|
||||||
|
|
||||||
public final function JSONObject SetNull(string key) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
local JSONKeyValuePair newKeyValuePair; |
|
||||||
local JSONStorageValue newStorageValue; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) |
|
||||||
{ |
|
||||||
index = data.length; |
|
||||||
} |
|
||||||
newStorageValue.type = JSON_Null; |
|
||||||
newKeyValuePair.key = key; |
|
||||||
newKeyValuePair.value = newStorageValue; |
|
||||||
data[index] = newKeyValuePair; |
|
||||||
return self; |
|
||||||
} |
|
||||||
|
|
||||||
// JSON array and object types don't have setters, but instead have |
|
||||||
// functions to create a new, empty array/object under a certain name. |
|
||||||
// They return object itself, allowing user to chain calls like this: |
|
||||||
// `object.CreateObject("folded object").CreateArray("names list");`. |
|
||||||
public final function JSONObject CreateArray(string key) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
local JSONKeyValuePair newKeyValuePair; |
|
||||||
local JSONStorageValue newStorageValue; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) |
|
||||||
{ |
|
||||||
index = data.length; |
|
||||||
} |
|
||||||
newStorageValue.type = JSON_Array; |
|
||||||
newStorageValue.complexValue = new class'JSONArray'; |
|
||||||
newKeyValuePair.key = key; |
|
||||||
newKeyValuePair.value = newStorageValue; |
|
||||||
data[index] = newKeyValuePair; |
|
||||||
return self; |
|
||||||
} |
|
||||||
|
|
||||||
public final function JSONObject CreateObject(string key) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
local JSONKeyValuePair newKeyValuePair; |
|
||||||
local JSONStorageValue newStorageValue; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) |
|
||||||
{ |
|
||||||
index = data.length; |
|
||||||
} |
|
||||||
newStorageValue.type = JSON_Object; |
|
||||||
newStorageValue.complexValue = new class'JSONObject'; |
|
||||||
newKeyValuePair.key = key; |
|
||||||
newKeyValuePair.value = newStorageValue; |
|
||||||
data[index] = newKeyValuePair; |
|
||||||
return self; |
|
||||||
} |
|
||||||
|
|
||||||
// Removes values with a given name. |
|
||||||
// Returns `true` if value was actually removed and `false` if it didn't exist. |
|
||||||
public final function bool RemoveValue(string key) |
|
||||||
{ |
|
||||||
local int index; |
|
||||||
index = GetIndex(key); |
|
||||||
if (index < 0) return false; |
|
||||||
|
|
||||||
data.Remove(index, 1); |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
defaultproperties |
|
||||||
{ |
|
||||||
} |
|
Reference in new issue