diff --git a/sources/Commands/ACommandFeature.uc b/sources/Commands/ACommandFeature.uc
index 5637297..a4e9e8b 100644
--- a/sources/Commands/ACommandFeature.uc
+++ b/sources/Commands/ACommandFeature.uc
@@ -17,28 +17,26 @@
* You should have received a copy of the GNU General Public License
* along with Acedia. If not, see .
*/
-class ACommandFeature extends Command;
+class ACommandFeature extends Command
+ dependson(PendingConfigsTool);
-// TODO: autoconf, newconf, deleteconf, setconf
+var private class selectedFeatureClass;
+var private Text selectedConfigName;
-struct EditedConfigs
-{
- var class featureClass;
- var HashTable pendingSaves;
-};
-var private array configEdits;
+var private PendingConfigsTool pendingConfigs;
+var private ACommandFeature_Announcer announcer;
-var private ACommandFeature_Announcer announcer;
+protected function Constructor()
+{
+ pendingConfigs =
+ PendingConfigsTool(_.memory.Allocate(class'PendingConfigsTool'));
+ super.Constructor();
+}
protected function Finalizer()
{
- local int i;
-
_.memory.Free(announcer);
- for (i = 0; i < configEdits.length; i ++) {
- _.memory.Free(configEdits[i].pendingSaves);
- }
- configEdits.length = 0;
+ _.memory.Free(pendingConfigs);
super.Finalizer();
}
@@ -69,122 +67,124 @@ protected function BuildData(CommandDataBuilder builder)
protected function Executed(CallData arguments, EPlayer instigator)
{
+ local Text userGivenFeatureName, userGivenConfigName;
+
announcer.Setup(none, instigator, othersConsole);
+ userGivenFeatureName = arguments.parameters.GetText(P("feature"));
+ selectedFeatureClass = LoadFeatureClass(userGivenFeatureName);
+ _.memory.Free(userGivenFeatureName);
+ userGivenConfigName = arguments.parameters.GetText(P("config"));
+ if (userGivenConfigName != none)
+ {
+ selectedConfigName = userGivenConfigName.LowerCopy();
+ userGivenConfigName.FreeSelf();
+ }
+ pendingConfigs.SelectConfig(selectedFeatureClass, selectedConfigName);
if (arguments.subCommandName.IsEmpty()) {
ShowAllFeatures();
}
- else if (arguments.subCommandName.Compare(P("enable")))
- {
- EnableFeature(
- arguments.parameters.GetText(P("feature")),
- arguments.parameters.GetText(P("config")));
+ else if (arguments.subCommandName.Compare(P("enable"))) {
+ EnableFeature();
}
else if (arguments.subCommandName.Compare(P("disable"))) {
- DisableFeature(arguments.parameters.GetText(P("feature")));
+ DisableFeature();
}
- else if (arguments.subCommandName.Compare(P("showconf")))
- {
- ShowFeatureConfig(
- arguments.parameters.GetText(P("feature")),
- arguments.parameters.GetText(P("config")));
+ else if (arguments.subCommandName.Compare(P("showconf"))) {
+ ShowFeatureConfig();
}
else if (arguments.subCommandName.Compare(P("editconf")))
{
EditFeatureConfig(
- arguments.parameters.GetText(P("feature")),
- arguments.parameters.GetText(P("config")),
arguments.parameters.GetText(P("variable path")),
arguments.parameters.GetText(P("value")));
}
+ _.memory.Free(selectedConfigName);
+ selectedConfigName = none;
}
-protected function EnableFeature(BaseText featureName, BaseText configParameter)
+protected function EnableFeature()
{
- local bool wasEnabled;
- local Text oldConfig, newConfig;
- local Feature instance;
- local class featureClass;
+ local bool wasEnabled;
+ local Text oldConfig, newConfig;
+ local Feature instance;
- featureClass = LoadFeatureClass(featureName);
- if (featureClass == none) {
- return;
- }
- wasEnabled = featureClass.static.IsEnabled();
- oldConfig = featureClass.static.GetCurrentConfig();
- newConfig = PickConfigBasedOnParameter(featureClass, configParameter);
+ wasEnabled = selectedFeatureClass.static.IsEnabled();
+ oldConfig = selectedFeatureClass.static.GetCurrentConfig();
+ newConfig = PickConfigBasedOnParameter();
// Already enabled with the same config!
if (oldConfig != none && oldConfig.Compare(newConfig, SCASE_INSENSITIVE))
{
- announcer.AnnounceFailedAlreadyEnabled(featureClass, newConfig);
+ announcer.AnnounceFailedAlreadyEnabled(selectedFeatureClass, newConfig);
_.memory.Free(newConfig);
_.memory.Free(oldConfig);
return;
}
// Try enabling and report the result
- instance = featureClass.static.EnableMe(newConfig);
- if (instance == none) {
- announcer.AnnounceFailedCannotEnableFeature(featureClass, newConfig);
+ instance = selectedFeatureClass.static.EnableMe(newConfig);
+ if (instance == none)
+ {
+ announcer.AnnounceFailedCannotEnableFeature(
+ selectedFeatureClass,
+ newConfig);
}
- else if (wasEnabled) {
- announcer.AnnounceSwappedConfig(featureClass, oldConfig, newConfig);
+ else if (wasEnabled)
+ {
+ announcer.AnnounceSwappedConfig(
+ selectedFeatureClass,
+ oldConfig,
+ newConfig);
}
else {
- announcer.AnnounceEnabledFeature(featureClass, newConfig);
+ announcer.AnnounceEnabledFeature(selectedFeatureClass, newConfig);
}
_.memory.Free(newConfig);
_.memory.Free(oldConfig);
}
-protected function DisableFeature(Text featureName)
+protected function DisableFeature()
{
- local class featureClass;
-
- featureClass = LoadFeatureClass(featureName);
- if (featureClass == none) {
- return;
- }
- if (!featureClass.static.IsEnabled())
+ if (!selectedFeatureClass.static.IsEnabled())
{
- announcer.AnnounceFailedAlreadyDisabled(featureClass);
+ announcer.AnnounceFailedAlreadyDisabled(selectedFeatureClass);
return;
}
- featureClass.static.DisableMe();
+ selectedFeatureClass.static.DisableMe();
// It is possible that this command itself is destroyed after above command
// so do the check just in case
if (IsAllocated()) {
- announcer.AnnounceDisabledFeature(featureClass);
+ announcer.AnnounceDisabledFeature(selectedFeatureClass);
}
}
-protected function ShowFeatureConfig(
- BaseText featureName,
- BaseText configParameter)
+protected function ShowFeatureConfig()
{
- local MutableText dataAsJSON;
- local HashTable currentData, pendingData;
- local class featureClass;
-
- featureClass = LoadFeatureClass(featureName);
- if (featureClass == none) return;
- if (configParameter == none) return;
+ local MutableText dataAsJSON;
+ local HashTable currentData, pendingData;
- currentData = GetCurrentConfigData(featureClass, configParameter);
+ if (selectedConfigName == none) {
+ return;
+ }
+ currentData = GetCurrentConfigData();
if (currentData == none)
{
- announcer.AnnounceFailedNoDataForConfig(featureClass, configParameter);
+ announcer.AnnounceFailedNoDataForConfig(
+ selectedFeatureClass,
+ selectedConfigName);
return;
}
// Display current data
dataAsJSON = _.json.PrettyPrint(currentData);
- announcer.AnnounceCurrentConfig(featureClass, configParameter);
+ announcer.AnnounceCurrentConfig(selectedFeatureClass, selectedConfigName);
callerConsole.Flush().WriteLine(dataAsJSON);
_.memory.Free(dataAsJSON);
// Display pending data
- pendingData = GetPendingConfigData(featureClass, configParameter);
+ pendingData = pendingConfigs.GetPendingConfigData();
if (pendingData != none)
{
dataAsJSON = _.json.PrettyPrint(pendingData);
- announcer.AnnouncePendingConfig(featureClass, configParameter);
+ announcer.AnnouncePendingConfig(
+ selectedFeatureClass,
+ selectedConfigName);
callerConsole.Flush().WriteLine(dataAsJSON);
_.memory.Free(dataAsJSON);
}
@@ -192,35 +192,30 @@ protected function ShowFeatureConfig(
_.memory.Free(currentData);
}
-protected function Text PickConfigBasedOnParameter(
- class featureClass,
- BaseText configParameter)
+protected function Text PickConfigBasedOnParameter()
{
local Text resolvedConfig;
local class configClass;
- if (featureClass == none) {
- return none;
- }
- configClass = featureClass.default.configClass;
+ configClass = selectedFeatureClass.default.configClass;
if (configClass == none)
{
- announcer.AnnounceFailedNoConfigClass(featureClass);
+ announcer.AnnounceFailedNoConfigClass(selectedFeatureClass);
return none;
}
// If config was specified - simply check that it exists
- if (configParameter != none)
+ if (selectedConfigName != none)
{
- if (configClass.static.Exists(configParameter)) {
- return configParameter.Copy();
+ if (configClass.static.Exists(selectedConfigName)) {
+ return selectedConfigName.Copy();
}
- announcer.AnnounceFailedConfigMissing(configParameter);
+ announcer.AnnounceFailedConfigMissing(selectedConfigName);
return none;
}
// If it wasn't specified - try auto config instead
resolvedConfig = configClass.static.GetAutoEnabledConfig();
if (resolvedConfig == none) {
- announcer.AnnounceFailedNoConfigProvided(featureClass);
+ announcer.AnnounceFailedNoConfigProvided(selectedFeatureClass);
}
return resolvedConfig;
}
@@ -260,7 +255,7 @@ protected function ShowFeature(class feature)
{
local int i;
local Text autoConfig;
- local MutableText featureName, builder;
+ local MutableText featureName, builder, nextConfig;
local ListBuilder configList;
local array availableConfigs;
local class configClass;
@@ -285,10 +280,10 @@ protected function ShowFeature(class feature)
builder.Append(featureName);
_.memory.Free(featureName);
if (availableConfigs.length == 1) {
- builder.Append(P(" with config:"));
+ builder.Append(P(" with config: "));
}
else if (availableConfigs.length > 1) {
- builder.Append(P(" with configs:"));
+ builder.Append(P(" with configs: "));
}
callerConsole.Write(builder);
_.memory.Free(builder);
@@ -296,7 +291,12 @@ protected function ShowFeature(class feature)
autoConfig = configClass.static.GetAutoEnabledConfig();
for (i = 0; i < availableConfigs.length; i += 1)
{
- configList.Item(availableConfigs[i]);
+ nextConfig = availableConfigs[i].MutableCopy();
+ if (pendingConfigs.HasPendingConfigFor(feature, nextConfig)) {
+ nextConfig.Append(P("*"));
+ }
+ configList.Item(nextConfig);
+ _.memory.Free(nextConfig);
if ( autoConfig != none
&& autoConfig.Compare(availableConfigs[i], SCASE_INSENSITIVE))
{
@@ -310,206 +310,43 @@ protected function ShowFeature(class feature)
_.memory.Free(autoConfig);
_.memory.Free(builder);
}
-//TODO: find where `null` spam is from
-//TODO add failure color to fail announcements and good color to good ones - add them too!
-protected function EditFeatureConfig(
- BaseText featureName,
- BaseText configParameter,
- BaseText pathToValue,
- BaseText newValue)
+
+protected function EditFeatureConfig(BaseText pathToValue, BaseText newValue)
{
- local int arrayIndex;
- local Text topValue;
- local HashTable pendingData;
- local JSONPointer pointer;
- local Parser parser;
- local AcediaObject jsonValue, container;
- local class featureClass;
+ local PendingConfigsTool.PendingConfigToolError error;
- featureClass = LoadFeatureClass(featureName);
- if (featureClass == none) {
- return;
- }
- pendingData = GetPendingConfigData(featureClass, configParameter, true);
- if (pendingData == none)
- {
- announcer.AnnounceFailedConfigMissing(configParameter);
- return;
- }
- // Get guaranteed not-`none` JSON value
- parser = newValue.Parse();
- jsonValue = _.json.ParseWith(parser);
- parser.FreeSelf();
- if (jsonValue == none) {
- jsonValue = newValue.Copy();
- }
- //
- pointer = _.json.Pointer(pathToValue);
- if (pointer.IsEmpty())
- {
- if (jsonValue.class != class'HashTable') {
- announcer.AnnounceFailedExpectedObject();
- }
- else {
- ChangePendingConfigData(featureClass, configParameter, HashTable(jsonValue));
- }
- jsonValue.FreeSelf();
- return;
- }
- topValue = pointer.Pop();
- container = pendingData.GetItemByJSON(pointer);
- if (container == none)
- {
- announcer.AnnounceFailedBadPointer(featureClass, configParameter, pathToValue);
- pointer.FreeSelf();
- topValue.FreeSelf();
- return;
+ error = pendingConfigs.ChangeConfig(pathToValue, newValue);
+ if (error == PCTE_ConfigMissing) {
+ announcer.AnnounceFailedConfigMissing(selectedConfigName);
}
- if (HashTable(container) != none) {
- HashTable(container).SetItem(topValue, jsonValue);
+ else if (error == PCTE_ExpectedObject) {
+ announcer.AnnounceFailedExpectedObject();
}
- if (ArrayList(container) != none)
+ else if (error == PCTE_BadPointer)
{
- parser = topValue.Parse();
- if (parser.MInteger(arrayIndex, 10).Ok()) {
- ArrayList(container).SetItem(arrayIndex, jsonValue);
- }
- else if (topValue.Compare(P("-"))) {
- ArrayList(container).AddItem(jsonValue);
- }
- else {
- announcer.AnnounceFailedBadPointer(featureClass, configParameter, pathToValue);
- }
- parser.FreeSelf();
- }
- pointer.FreeSelf();
- topValue.FreeSelf();
-}
-
-/*// TODO: autoconf, newconf, deleteconf, setconf
-
-struct EditedConfigs
-{
- var class featureClass;
- var HashTable pendingSaves;
-};
-var private array configEdits;*/
-
-private function HashTable GetConfigData(
- class featureClass,
- BaseText configName)
-{
- local HashTable result;
-
- if (featureClass == none) return none;
- if (configName == none) return none;
-
- result = GetPendingConfigData(featureClass, configName);
- if (result != none) {
- return result;
+ announcer.AnnounceFailedBadPointer(
+ selectedFeatureClass,
+ selectedConfigName,
+ pathToValue);
}
- return GetCurrentConfigData(featureClass, configName);
}
-private function HashTable GetCurrentConfigData(
- class featureClass,
- BaseText configName)
+private function HashTable GetCurrentConfigData()
{
local class configClass;
- if (featureClass == none) return none;
- if (configName == none) return none;
-
- configClass = featureClass.default.configClass;
- if (configClass == none)
- {
- announcer.AnnounceFailedNoConfigClass(featureClass);
+ if (selectedConfigName == none) {
return none;
}
- return configClass.static.LoadData(configName);
-}
-
-private function int GetPendingConfigDataIndex(
- class featureClass)
-{
- local int i;
-
- for (i = 0; i < configEdits.length; i ++)
- {
- if (configEdits[i].featureClass == featureClass) {
- return i;
- }
- }
- return -1;
-}
-
-private function ChangePendingConfigData(
- class featureClass,
- BaseText configName,
- HashTable newData)
-{
- local int editsIndex;
- local Text lowerCaseConfigName;
-
- if (newData == none) return;
- if (configName == none) return;
- editsIndex = GetPendingConfigDataIndex(featureClass);
- if (editsIndex < 0) return;
-
- lowerCaseConfigName = configName.LowerCopy();
- configEdits[editsIndex].pendingSaves.SetItem(configName, newData);
- lowerCaseConfigName.FreeSelf();
-}
-
-private function HashTable GetPendingConfigData(
- class featureClass,
- BaseText configName,
- optional bool createIfMissing)
-{
- local int editsIndex;
- local Text lowerCaseConfigName;
- local HashTable result;
- local EditedConfigs newRecord;
-
- if (featureClass == none) return none;
- if (configName == none) return none;
-
- lowerCaseConfigName = configName.LowerCopy();
- editsIndex = GetPendingConfigDataIndex(featureClass);
- if (editsIndex >= 0)
- {
- result = configEdits[editsIndex]
- .pendingSaves
- .GetHashTable(lowerCaseConfigName);
- if (result != none)
- {
- lowerCaseConfigName.FreeSelf();
- return result;
- }
- }
- if (createIfMissing)
+ configClass = selectedFeatureClass.default.configClass;
+ if (configClass == none)
{
- if (editsIndex < 0)
- {
- editsIndex = configEdits.length;
- newRecord.featureClass = featureClass;
- newRecord.pendingSaves = _.collections.EmptyHashTable();
- configEdits[editsIndex] = newRecord;
- }
- result = GetCurrentConfigData(featureClass, configName);
- if (result != none)
- {
- configEdits[editsIndex]
- .pendingSaves
- .SetItem(lowerCaseConfigName, result);
- }
+ announcer.AnnounceFailedNoConfigClass(selectedFeatureClass);
+ return none;
}
- lowerCaseConfigName.FreeSelf();
- return result;
+ return configClass.static.LoadData(selectedConfigName);
}
-// 3. Add `editconf` subcommand
-// 4. Add '*' for edited configs in feature display
// 5. Add `saveconf` and `--save` flag
// 6. Add `removeconf`
// 7. Add `newconf`
diff --git a/sources/Commands/ACommandFeature_Announcer.uc b/sources/Commands/ACommandFeature_Announcer.uc
index 32fc19e..74b56b0 100644
--- a/sources/Commands/ACommandFeature_Announcer.uc
+++ b/sources/Commands/ACommandFeature_Announcer.uc
@@ -178,7 +178,7 @@ public final function AnnounceFailedNoConfigProvided(
{
failedNoConfigProvided.initialized = true;
failedNoConfigProvided.toSelfReport = _.text.MakeTemplate_S(
- "{$TextFailue No config specified} and {$TextFailure no"
+ "{$TextFailure No config specified} and {$TextFailure no"
@ "auto-enabled config} exists for feature {$TextEmphasis `%1`}");
}
failedNoConfigProvided.toSelfReport.Reset().ArgClass(featureClass);
@@ -191,7 +191,7 @@ public final function AnnounceFailedConfigMissing(BaseText config)
{
failedConfigMissing.initialized = true;
failedConfigMissing.toSelfReport = _.text.MakeTemplate_S(
- "Specified config \"%1\" {$TextFailue doesn't exist}");
+ "Specified config \"%1\" {$TextFailure doesn't exist}");
}
failedConfigMissing.toSelfReport.Reset().Arg(config);
MakeAnnouncement(failedConfigMissing);
@@ -269,7 +269,8 @@ public final function AnnounceFailedNoDataForConfig(
{
failedNoDataForConfig.initialized = true;
failedNoDataForConfig.toSelfReport = _.text.MakeTemplate_S(
- "Feature {$TextEmphasis `%1`} is missing data for config \"%2\"");
+ "Feature {$TextEmphasis `%1`} is {$TextFailure missing data} for"
+ @ "config \"%2\"");
}
failedNoDataForConfig.toSelfReport
.Reset()
@@ -284,8 +285,8 @@ public final function AnnounceFailedExpectedObject()
{
failedExpectedObject.initialized = true;
failedExpectedObject.toSelfReport = _.text.MakeTemplate_S(
- "When changing the value of the whole config, a JSON object must be"
- @ "provided");
+ "Value change {$TextFailure failed}, because when changing"
+ @ "the value of the whole config, a JSON object must be provided");
}
MakeAnnouncement(failedExpectedObject);
}
@@ -299,8 +300,8 @@ public final function AnnounceFailedBadPointer(
{
failedBadPointer.initialized = true;
failedBadPointer.toSelfReport = _.text.MakeTemplate_S(
- "Provided JSON pointer \"%3\" is invalid for config \"%2\" of"
- @ "feature {$TextEmphasis `%1`}");
+ "Provided JSON pointer \"%3\" is {$TextFailure invalid} for config"
+ @ "\"%2\" of feature {$TextEmphasis `%1`}");
}
failedBadPointer.toSelfReport
.Reset()
diff --git a/sources/Tools/PendingConfigsTool.uc b/sources/Tools/PendingConfigsTool.uc
new file mode 100644
index 0000000..e32d977
--- /dev/null
+++ b/sources/Tools/PendingConfigsTool.uc
@@ -0,0 +1,271 @@
+/**
+ * Auxiliary object for `ACommandFeature` to help with managing pending
+ * configs for `Feature`s. Pending configs are `HashTable`s with config data
+ * that are yet to be applied to configs and `Feature`s. They allow users to
+ * make several changes to the data before actually making changes to
+ * the gameplay code.
+ * Copyright 2022 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 PendingConfigsTool extends AcediaObject;
+
+var private class selectedFeatureClass;
+var private Text selectedConfigName;
+
+enum PendingConfigToolError
+{
+ PCTE_None,
+ PCTE_ConfigMissing,
+ PCTE_ExpectedObject,
+ PCTE_BadPointer
+};
+
+struct PendingConfigs
+{
+ var class featureClass;
+ var HashTable pendingSaves;
+};
+var private array featurePendingEdits;
+
+protected function Finalizer()
+{
+ local int i;
+
+ for (i = 0; i < featurePendingEdits.length; i ++) {
+ _.memory.Free(featurePendingEdits[i].pendingSaves);
+ }
+ featurePendingEdits.length = 0;
+}
+
+public final function SelectConfig(
+ class featureClass,
+ BaseText configName)
+{
+ _.memory.Free(selectedConfigName);
+ selectedFeatureClass = featureClass;
+ selectedConfigName = none;
+ if (configName != none) {
+ selectedConfigName = configName.LowerCopy();
+ }
+}
+
+public function bool HasPendingConfigFor(
+ class featureClass,
+ BaseText configName)
+{
+ local int i;
+ local bool result;
+ local Text lowerCaseConfigName;
+
+ if (featureClass == none) return false;
+ if (configName == none) return false;
+
+ for (i = 0; i < featurePendingEdits.length; i ++)
+ {
+ if (featurePendingEdits[i].featureClass == featureClass)
+ {
+ lowerCaseConfigName = configName.LowerCopy();
+ result = featurePendingEdits[i].pendingSaves
+ .HasKey(lowerCaseConfigName);
+ lowerCaseConfigName.FreeSelf();
+ return result;
+ }
+ }
+ return false;
+}
+
+public function HashTable GetPendingConfigData(optional bool createIfMissing)
+{
+ local int editsIndex;
+ local HashTable result;
+ local PendingConfigs newRecord;
+
+ if (selectedConfigName == none) {
+ return none;
+ }
+ editsIndex = GetPendingConfigDataIndex();
+ if (editsIndex >= 0)
+ {
+ result = featurePendingEdits[editsIndex]
+ .pendingSaves
+ .GetHashTable(selectedConfigName);
+ if (result != none) {
+ return result;
+ }
+ }
+ if (createIfMissing)
+ {
+ if (editsIndex < 0)
+ {
+ editsIndex = featurePendingEdits.length;
+ newRecord.featureClass = selectedFeatureClass;
+ newRecord.pendingSaves = _.collections.EmptyHashTable();
+ featurePendingEdits[editsIndex] = newRecord;
+ }
+ result = GetCurrentConfigData();
+ if (result != none)
+ {
+ featurePendingEdits[editsIndex]
+ .pendingSaves
+ .SetItem(selectedConfigName, result);
+ }
+ }
+ return result;
+}
+
+public function PendingConfigToolError ChangeConfig(
+ BaseText pathToValue,
+ BaseText newValue)
+{
+ local HashTable pendingData;
+ local JSONPointer pointer;
+ local Parser parser;
+ local AcediaObject newValueAsJSON;
+ local PendingConfigToolError result;
+
+ if (pathToValue == none) {
+ return PCTE_BadPointer;
+ }
+ pendingData = GetPendingConfigData(true);
+ if (pendingData == none) {
+ return PCTE_ConfigMissing;
+ }
+ // Get guaranteed not-`none` JSON value, treating it as JSON string
+ // if necessary
+ parser = _.text.Parse(newValue);
+ newValueAsJSON = _.json.ParseWith(parser);
+ parser.FreeSelf();
+ if (newValueAsJSON == none && newValue != none) {
+ newValueAsJSON = newValue.Copy();
+ }
+ // Set new data
+ pointer = _.json.Pointer(pathToValue);
+ result = SetItemByJSON(pendingData, pointer, newValueAsJSON);
+ pointer.FreeSelf();
+ pendingData.FreeSelf();
+ _.memory.Free(newValueAsJSON);
+ return result;
+}
+
+private function PendingConfigToolError SetItemByJSON(
+ HashTable data,
+ JSONPointer pointer,
+ AcediaObject jsonValue)
+{
+ local Text containerIndex;
+ local AcediaObject container;
+ local PendingConfigToolError result;
+
+ if (pointer.IsEmpty())
+ {
+ if (HashTable(jsonValue) != none)
+ {
+ result = ChangePendingConfigData(HashTable(jsonValue));
+ _.memory.Free(jsonValue);
+ return result;
+ }
+ _.memory.Free(jsonValue);
+ return PCTE_ExpectedObject;
+ }
+ // Since `!pointer.IsEmpty()`, we are guaranteed to pop a valid value
+ containerIndex = pointer.Pop();
+ container = data.GetItemByJSON(pointer);
+ if (container == none)
+ {
+ containerIndex.FreeSelf();
+ return PCTE_BadPointer;
+ }
+ result = SetContainerItemByText(container, containerIndex, jsonValue);
+ containerIndex.FreeSelf();
+ container.FreeSelf();
+ return result;
+}
+
+private function PendingConfigToolError SetContainerItemByText(
+ AcediaObject container,
+ BaseText containerIndex,
+ AcediaObject jsonValue)
+{
+ local int arrayIndex;
+ local Parser parser;
+ local ArrayList arrayListContainer;
+ local HashTable hashTableContainer;
+
+ hashTableContainer = HashTable(container);
+ arrayListContainer = ArrayList(container);
+ if (hashTableContainer != none) {
+ hashTableContainer.SetItem(containerIndex, jsonValue);
+ }
+ if (arrayListContainer != none)
+ {
+ parser = containerIndex.Parse();
+ if (parser.MInteger(arrayIndex, 10).Ok())
+ {
+ arrayListContainer.SetItem(arrayIndex, jsonValue);
+ parser.FreeSelf();
+ return PCTE_None;
+ }
+ parser.FreeSelf();
+ if (containerIndex.Compare(P("-"))) {
+ arrayListContainer.AddItem(jsonValue);
+ }
+ else {
+ return PCTE_BadPointer;
+ }
+ }
+ return PCTE_None;
+}
+
+private function int GetPendingConfigDataIndex()
+{
+ local int i;
+
+ for (i = 0; i < featurePendingEdits.length; i ++)
+ {
+ if (featurePendingEdits[i].featureClass == selectedFeatureClass) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+private function PendingConfigToolError ChangePendingConfigData(
+ HashTable newData)
+{
+ local int editsIndex;
+
+ if (selectedConfigName == none) {
+ return PCTE_None;
+ }
+ editsIndex = GetPendingConfigDataIndex();
+ if (editsIndex < 0) {
+ return PCTE_ConfigMissing;
+ }
+ featurePendingEdits[editsIndex].pendingSaves
+ .SetItem(selectedConfigName, newData);
+ return PCTE_None;
+}
+
+private function HashTable GetCurrentConfigData()
+{
+ return selectedFeatureClass.default.configClass.static
+ .LoadData(selectedConfigName);
+}
+
+defaultproperties
+{
+}
\ No newline at end of file