Browse Source

Change `Iter` to be general iterator class

Previously `Iter` was meant to be a collection iterator class, but now
we need a more generalized notion of iterator, so we move some
collection-specific methods out and designate `Iter` a general iterator
class, while `CollectionIterator` takes its former place.
pull/8/head
Anton Tarasenko 2 years ago
parent
commit
b569e8e563
  1. 12
      sources/Commands/Commands_Feature.uc
  2. 66
      sources/CoreRealm/Iter.uc
  3. 2
      sources/Data/Collections/ArrayListIterator.uc
  4. 2
      sources/Data/Collections/AssociativeArrayIterator.uc
  5. 9
      sources/Data/Collections/Collection.uc
  6. 50
      sources/Data/Collections/CollectionIterator.uc
  7. 2
      sources/Data/Collections/DynamicArrayIterator.uc
  8. 2
      sources/Data/Collections/HashTableIterator.uc
  9. 40
      sources/Data/Collections/Tests/TEST_Iterator.uc
  10. 13
      sources/Data/Collections/Tests/TEST_IteratorOld.uc
  11. 10
      sources/Data/Database/Local/DBRecord.uc
  12. 26
      sources/Gameplay/BaseClasses/Frontend/World/AWorldComponent.uc
  13. 44
      sources/Text/JSON/JSONAPI.uc

12
sources/Commands/Commands_Feature.uc

@ -265,12 +265,12 @@ public final function RegisterCommand(class<Command> commandClass)
*/ */
public final function RemoveCommand(class<Command> commandClass) public final function RemoveCommand(class<Command> commandClass)
{ {
local int i; local int i;
local Iter iter; local CollectionIterator iter;
local Command nextCommand; local Command nextCommand;
local Text nextCommandName; local Text nextCommandName;
local array<Text> commandGroup; local array<Text> commandGroup;
local array<Text> keysToRemove; local array<Text> keysToRemove;
if (commandClass == none) return; if (commandClass == none) return;
if (registeredCommands == none) return; if (registeredCommands == none) return;

66
sources/CoreRealm/Iter.uc

@ -0,0 +1,66 @@
/**
* Base class for iterator, an auxiliary object for iterating through
* a set of objects obtained from some context-dependent source.
* 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 <https://www.gnu.org/licenses/>.
*/
class Iter extends AcediaObject
abstract;
/**
* Makes iterator pick next item.
* Use `HasFinished()` to check whether you have iterated all of them.
*
* @param skipNone @deprecated
* Set this to `true` if you want to skip all stored
* values that are equal to `none`. By default does not skip them.
* Since order of iterating through items is not guaranteed, at each
* `Next()` call an arbitrary set of items can be skipped.
* @return Reference to caller `Iterator` to allow for method chaining.
*/
public function Iter Next(optional bool skipNone);
/**
* Returns current value pointed to by an iterator.
*
* Does not advance iteration: use `Next()` to pick next value.
*
* @return Current value being iterated over. If `Iterator()` has finished
* iterating over all values or was not initialized - returns `none`.
* Note that depending on context `none` values can also be returned,
* use `LeaveOnlyNotNone()` method to prevent that.
*/
public function AcediaObject Get();
/**
* Checks if caller `Iterator` has finished iterating.
*
* @return `true` if caller `Iterator` has finished iterating or
* was not initialized. `false` otherwise.
*/
public function bool HasFinished();
/**
* Makes caller iterator skip any `none` items during iteration.
*
* @return Reference to caller `Iterator` to allow for method chaining.
*/
public function Iter LeaveOnlyNotNone();
defaultproperties
{
}

2
sources/Data/Collections/ArrayListIterator.uc

@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Acedia. If not, see <https://www.gnu.org/licenses/>. * along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/ */
class ArrayListIterator extends Iter class ArrayListIterator extends CollectionIterator
dependson(ArrayList); dependson(ArrayList);
var private ArrayList relevantCollection; var private ArrayList relevantCollection;

2
sources/Data/Collections/AssociativeArrayIterator.uc

@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Acedia. If not, see <https://www.gnu.org/licenses/>. * along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/ */
class AssociativeArrayIterator extends Iter class AssociativeArrayIterator extends CollectionIterator
dependson(AssociativeArray); dependson(AssociativeArray);
var private bool hasNotFinished; var private bool hasNotFinished;

9
sources/Data/Collections/Collection.uc

@ -22,7 +22,7 @@
class Collection extends AcediaObject class Collection extends AcediaObject
abstract; abstract;
var protected class<Iter> iteratorClass; var protected class<CollectionIterator> iteratorClass;
/** /**
* Method that must be overloaded for `GetItemByPointer()` to properly work. * Method that must be overloaded for `GetItemByPointer()` to properly work.
@ -46,10 +46,11 @@ protected function AcediaObject GetByText(BaseText key);
* @return New initialized `Iterator` that will iterate over all items in * @return New initialized `Iterator` that will iterate over all items in
* a given collection. Guaranteed to be not `none`. * a given collection. Guaranteed to be not `none`.
*/ */
public final function Iter Iterate() public final function CollectionIterator Iterate()
{ {
local Iter newIterator; local CollectionIterator newIterator;
newIterator = Iter(_.memory.Allocate(iteratorClass));
newIterator = CollectionIterator(_.memory.Allocate(iteratorClass));
if (!newIterator.Initialize(self)) if (!newIterator.Initialize(self))
{ {
// This should not ever happen. // This should not ever happen.

50
sources/Data/Collections/Iter.uc → sources/Data/Collections/CollectionIterator.uc

@ -1,9 +1,9 @@
/** /**
* Base class for iterator, an auxiliary object for iterating through * Base class for collection iterators, an auxiliary object for iterating
* objects stored inside an Acedia's collection. * through objects stored inside an Acedia's collection.
* Iterators expect that collection remains unchanged while they * Iterators expect that collection remains unchanged while they
* are iterating through it. Otherwise their behavior becomes undefined. * are iterating through it. Otherwise their behavior becomes undefined.
* Copyright 2020 Anton Tarasenko * Copyright 2020-2022 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
* *
@ -20,7 +20,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Acedia. If not, see <https://www.gnu.org/licenses/>. * along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/ */
class Iter extends AcediaObject class CollectionIterator extends Iter
abstract; abstract;
/** /**
@ -40,33 +40,6 @@ class Iter extends AcediaObject
*/ */
public function bool Initialize(Collection relevantCollection); public function bool Initialize(Collection relevantCollection);
/**
* Makes iterator pick next item in collection.
* As long as collection that's being iterated over is not modified,
* `Next()` is guaranteed to iterate over all it's items.
* Use `HasFinished()` to check whether you have iterated all of them.
* Order of iteration is not guaranteed.
*
* @param skipNone Set this to `true` if you want to skip all stored
* values that are equal to `none`. By default does not skip them.
* Since order of iterating through items is not guaranteed, at each
* `Next()` call an arbitrary set of items can be skipped.
* @return Reference to caller `Iterator` to allow for method chaining.
*/
public function Iter Next(optional bool skipNone);
/**
* Returns current value pointed to by an iterator.
*
* Does not advance iteration: use `Next()` to pick next value.
*
* @return Current value being iterated over. If `Iterator()` has finished
* iterating over all values or was not initialized - returns `none`.
* Note that `none` can also be returned if it's stored in a collection,
* use `LeaveOnlyNotNone()` method to prevent that.
*/
public function AcediaObject Get();
/** /**
* Returns key of current value pointed to by an iterator. * Returns key of current value pointed to by an iterator.
* *
@ -83,21 +56,6 @@ public function AcediaObject Get();
*/ */
public function AcediaObject GetKey(); public function AcediaObject GetKey();
/**
* Checks if caller `Iterator` has finished iterating.
*
* @return `true` if caller `Iterator` has finished iterating or
* was not initialized. `false` otherwise.
*/
public function bool HasFinished();
/**
* Makes caller iterator skip any `none` items during iteration.
*
* @return Reference to caller `Iterator` to allow for method chaining.
*/
public function Iter LeaveOnlyNotNone();
defaultproperties defaultproperties
{ {
} }

2
sources/Data/Collections/DynamicArrayIterator.uc

@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Acedia. If not, see <https://www.gnu.org/licenses/>. * along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/ */
class DynamicArrayIterator extends Iter; class DynamicArrayIterator extends CollectionIterator;
var private DynamicArray relevantCollection; var private DynamicArray relevantCollection;
var private int currentIndex; var private int currentIndex;

2
sources/Data/Collections/HashTableIterator.uc

@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Acedia. If not, see <https://www.gnu.org/licenses/>. * along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/ */
class HashTableIterator extends Iter class HashTableIterator extends CollectionIterator
dependson(HashTable); dependson(HashTable);
var private bool hasNotFinished; var private bool hasNotFinished;

40
sources/Data/Collections/Tests/TEST_Iterator.uc

@ -41,9 +41,9 @@ protected static function ResetFlags()
} }
protected static function DoTestIterator( protected static function DoTestIterator(
string issueSubjectAllocation, string issueSubjectAllocation,
string issueSubjectAmount, string issueSubjectAmount,
Iter iter) CollectionIterator iter)
{ {
local int i; local int i;
local int seenCount; local int seenCount;
@ -92,9 +92,9 @@ protected static function TESTS()
protected static function Test_ArrayList() protected static function Test_ArrayList()
{ {
local int i; local int i;
local Iter iter; local CollectionIterator iter;
local ArrayList array; local ArrayList array;
array = ArrayList(__().memory.Allocate(class'ArrayList')); array = ArrayList(__().memory.Allocate(class'ArrayList'));
iter = array.Iterate(); iter = array.Iterate();
@ -126,9 +126,9 @@ protected static function Test_ArrayList()
protected static function Test_HashTable() protected static function Test_HashTable()
{ {
local int i; local int i;
local Iter iter; local CollectionIterator iter;
local HashTable array; local HashTable array;
array = HashTable(__().memory.Allocate(class'HashTable')); array = HashTable(__().memory.Allocate(class'HashTable'));
iter = array.Iterate(); iter = array.Iterate();
@ -166,10 +166,10 @@ protected static function Test_IterationAndNone()
protected static function SubTest_ArrayListIterationAndNone() protected static function SubTest_ArrayListIterationAndNone()
{ {
local bool sawNone; local bool sawNone;
local int counter; local int counter;
local Iter iter; local CollectionIterator iter;
local ArrayList list; local ArrayList list;
list = __().collections.EmptyArrayList(); list = __().collections.EmptyArrayList();
list.AddItem(__().box.int(1)); list.AddItem(__().box.int(1));
@ -192,7 +192,8 @@ protected static function SubTest_ArrayListIterationAndNone()
@ "`LeaveOnlyNotNone()` call."); @ "`LeaveOnlyNotNone()` call.");
sawNone = false; sawNone = false;
counter = 0; counter = 0;
iter = list.Iterate().LeaveOnlyNotNone(); iter = list.Iterate();
iter.LeaveOnlyNotNone();
while (!iter.HasFinished()) while (!iter.HasFinished())
{ {
sawNone = sawNone || (iter.Get() == none); sawNone = sawNone || (iter.Get() == none);
@ -205,10 +206,10 @@ protected static function SubTest_ArrayListIterationAndNone()
protected static function SubTest_HashTableIterationAndNone() protected static function SubTest_HashTableIterationAndNone()
{ {
local bool sawNone; local bool sawNone;
local int counter; local int counter;
local Iter iter; local CollectionIterator iter;
local HashTable table; local HashTable table;
table = __().collections.EmptyHashTable(); table = __().collections.EmptyHashTable();
table.SetItem(__().box.float(1.0), __().box.int(1)); table.SetItem(__().box.float(1.0), __().box.int(1));
@ -231,7 +232,8 @@ protected static function SubTest_HashTableIterationAndNone()
@ "`LeaveOnlyNotNone()` call."); @ "`LeaveOnlyNotNone()` call.");
sawNone = false; sawNone = false;
counter = 0; counter = 0;
iter = table.Iterate().LeaveOnlyNotNone(); iter = table.Iterate();
iter.LeaveOnlyNotNone();
while (!iter.HasFinished()) while (!iter.HasFinished())
{ {
sawNone = sawNone || (iter.Get() == none); sawNone = sawNone || (iter.Get() == none);

13
sources/Data/Collections/Tests/TEST_IteratorOld.uc

@ -75,9 +75,10 @@ protected static function TESTS()
protected static function Test_DynamicArray() protected static function Test_DynamicArray()
{ {
local int i; local int i;
local Iter iter; local CollectionIterator iter;
local DynamicArray array; local DynamicArray array;
array = DynamicArray(__().memory.Allocate(class'DynamicArray')); array = DynamicArray(__().memory.Allocate(class'DynamicArray'));
iter = array.Iterate(); iter = array.Iterate();
Context("Testing iterator for `DynamicArray`"); Context("Testing iterator for `DynamicArray`");
@ -105,9 +106,9 @@ protected static function Test_DynamicArray()
protected static function Test_AssociativeArray() protected static function Test_AssociativeArray()
{ {
local int i; local int i;
local Iter iter; local CollectionIterator iter;
local AssociativeArray array; local AssociativeArray array;
array = AssociativeArray(__().memory.Allocate(class'AssociativeArray')); array = AssociativeArray(__().memory.Allocate(class'AssociativeArray'));
iter = array.Iterate(); iter = array.Iterate();
Context("Testing iterator for `AssociativeArray`"); Context("Testing iterator for `AssociativeArray`");

10
sources/Data/Database/Local/DBRecord.uc

@ -922,11 +922,11 @@ private final function FromArrayList(ArrayList source)
// Does not do any validation check. // Does not do any validation check.
private final function FromHashTable(HashTable source) private final function FromHashTable(HashTable source)
{ {
local int i, originalStorageLength; local int i, originalStorageLength;
local Iter iter; local CollectionIterator iter;
local string nextKey; local string nextKey;
local bool isNewKey; local bool isNewKey;
local AcediaObject nextObject; local AcediaObject nextObject;
originalStorageLength = storage.length; originalStorageLength = storage.length;
for (iter = source.Iterate(); !iter.HasFinished(); iter.Next()) for (iter = source.Iterate(); !iter.HasFinished(); iter.Next())
{ {

26
sources/Gameplay/BaseClasses/Frontend/World/AWorldComponent.uc

@ -0,0 +1,26 @@
/**
* Subset of functionality for dealing with basic game world interactions:
* searching for entities, tracing, etc..
* 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 <https://www.gnu.org/licenses/>.
*/
class AWorldComponent extends AcediaObject
abstract;
defaultproperties
{
}

44
sources/Text/JSON/JSONAPI.uc

@ -1226,11 +1226,11 @@ public final function MutableText PrintArrayList(ArrayList toPrint)
*/ */
public final function MutableText PrintObject(AssociativeArray toPrint) public final function MutableText PrintObject(AssociativeArray toPrint)
{ {
local bool printedKeyValuePair; local bool printedKeyValuePair;
local Iter iter; local CollectionIterator iter;
local Text nextKey; local Text nextKey;
local AcediaObject nextValue; local AcediaObject nextValue;
local MutableText result, printedKey, printedValue; local MutableText result, printedKey, printedValue;
if (toPrint == none) return none; if (toPrint == none) return none;
result = T(default.TOPEN_BRACE).MutableCopy(); result = T(default.TOPEN_BRACE).MutableCopy();
@ -1285,11 +1285,11 @@ public final function MutableText PrintObject(AssociativeArray toPrint)
*/ */
public final function MutableText PrintHashTable(HashTable toPrint) public final function MutableText PrintHashTable(HashTable toPrint)
{ {
local bool printedKeyValuePair; local bool printedKeyValuePair;
local Iter iter; local CollectionIterator iter;
local Text nextKey; local Text nextKey;
local AcediaObject nextValue; local AcediaObject nextValue;
local MutableText result, printedKey, printedValue; local MutableText result, printedKey, printedValue;
if (toPrint == none) { if (toPrint == none) {
return none; return none;
@ -1650,12 +1650,12 @@ private final function MutableText PrettyPrintObjectWithIndent(
AssociativeArray toPrint, AssociativeArray toPrint,
MutableText accumulatedIndent) MutableText accumulatedIndent)
{ {
local bool printedKeyValuePair; local bool printedKeyValuePair;
local Iter iter; local CollectionIterator iter;
local Text nextKey; local Text nextKey;
local AcediaObject nextValue; local AcediaObject nextValue;
local MutableText extendedIndent; local MutableText extendedIndent;
local MutableText result; local MutableText result;
if (toPrint == none) { if (toPrint == none) {
return none; return none;
} }
@ -1693,12 +1693,12 @@ private final function MutableText PrettyPrintHashTableWithIndent(
HashTable toPrint, HashTable toPrint,
MutableText accumulatedIndent) MutableText accumulatedIndent)
{ {
local bool printedKeyValuePair; local bool printedKeyValuePair;
local Iter iter; local CollectionIterator iter;
local Text nextKey; local Text nextKey;
local AcediaObject nextValue; local AcediaObject nextValue;
local MutableText extendedIndent; local MutableText extendedIndent;
local MutableText result; local MutableText result;
if (toPrint == none) { if (toPrint == none) {
return none; return none;
} }

Loading…
Cancel
Save