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