Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Content.Tests/DMProject/Tests/List/ListIndexToKey.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/proc/RunTest()
var/list/A = list("thing")
ASSERT(A[1] == "thing")

A["thing"] = 6
ASSERT(A["thing"] == 6)

var/list/L = list()
for(var/i in 1 to 5)
L.Add("[i]")
L["[i]"] = "item [i]"
ASSERT(length(L) == 5)
ASSERT(L["3"] == "item 3")
12 changes: 12 additions & 0 deletions OpenDreamRuntime/Objects/Types/DreamAssocList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,16 @@ public bool ContainsValue(DreamValue value) {
return _values.ContainsKey(value);
}

public override DreamValue OperatorAppend(DreamValue b) {
if (b.TryGetValueAsDreamList(out var bList)) {
foreach (var value in bList.EnumerateValues()) {
AddValue(value);
}
} else {
AddValue(b);
}

return new(this);
}

}
179 changes: 168 additions & 11 deletions OpenDreamRuntime/Objects/Types/DreamList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public class DreamList : DreamObject, IDreamList {

public virtual bool IsAssociative => _associativeValues is { Count: > 0 };

/// <summary>
/// Looks up the key to find the index
/// </summary>
private readonly Dictionary<DreamValue, int> _reverseLookup = [];
private readonly List<DreamValue> _values;
private Dictionary<DreamValue, DreamValue>? _associativeValues;

Expand All @@ -29,6 +33,12 @@ public DreamList(DreamObjectDefinition listDef, int size) : base(listDef) {
if (size >= DreamManager.ListPoolThreshold && ListPool.TryPop(out var poppedValues)) {
_values = poppedValues;
_values.EnsureCapacity(size);
foreach (var value in poppedValues) {
if (!_reverseLookup.TryAdd(value, 1)) {
_reverseLookup[value] += 1;
}
}

} else {
_values = new List<DreamValue>(size);
}
Expand All @@ -39,6 +49,11 @@ public DreamList(DreamObjectDefinition listDef, int size) : base(listDef) {
/// </summary>
public DreamList(DreamObjectDefinition listDef, List<DreamValue> values, Dictionary<DreamValue, DreamValue>? associativeValues) : base(listDef) {
_values = values;
foreach (var value in values) {
if (!_reverseLookup.TryAdd(value, 1)) {
_reverseLookup[value] += 1;
}
}
_associativeValues = associativeValues;

#if TOOLS
Expand Down Expand Up @@ -172,13 +187,31 @@ public virtual DreamValue GetValue(DreamValue key) {

public virtual void SetValue(DreamValue key, DreamValue value, bool allowGrowth = false) {
if (key.TryGetValueAsInteger(out int keyInteger)) {
if (allowGrowth && keyInteger == _values.Count + 1) {
var index = _values.Count + 1;
if (allowGrowth && keyInteger == index) {
_values.Add(value);

if (!_reverseLookup.TryAdd(value, 1)) {
_reverseLookup[value] += 1;
}
} else {
var oldValue = _values[keyInteger - 1];
var rLCount = _reverseLookup[oldValue] -= 1;
if(rLCount <= 0) {
_reverseLookup.Remove(oldValue);
}

_values[keyInteger - 1] = value;

if (!_reverseLookup.TryAdd(value, 1)) {
_reverseLookup[value] += 1;
}

}
} else {
if (!ContainsValue(key)) _values.Add(key);
if (_reverseLookup.TryAdd(key, 1)) {
_values.Add(key);
}

_associativeValues ??= new Dictionary<DreamValue, DreamValue>(1);
_associativeValues[key] = value;
Expand All @@ -191,6 +224,13 @@ public virtual void RemoveValue(DreamValue value) {
int valueIndex = _values.LastIndexOf(value);

if (valueIndex != -1) {
if (_reverseLookup.ContainsKey(value)) {
var rLCount = _reverseLookup[value] -= 1;
if (rLCount <= 0) {
_reverseLookup.Remove(value);
}
}

_associativeValues?.Remove(value);
_values.RemoveAt(valueIndex);
}
Expand All @@ -199,18 +239,17 @@ public virtual void RemoveValue(DreamValue value) {
}

public virtual void AddValue(DreamValue value) {
_values.Add(value);
_values.Add(value);
if (!_reverseLookup.TryAdd(value, 1)) {
_reverseLookup[value] += 1;
}

UpdateTracyContentsMemory();
}

//Does not include associations
public virtual bool ContainsValue(DreamValue value) {
for (int i = 0; i < _values.Count; i++) {
if (_values[i].Equals(value))
return true;
}

return false;
return _reverseLookup.ContainsKey(value);
}

public virtual bool ContainsKey(DreamValue value) {
Expand All @@ -220,6 +259,8 @@ public virtual bool ContainsKey(DreamValue value) {
public virtual int FindValue(DreamValue value, int start = 1, int end = 0) {
if (end == 0 || end > _values.Count) end = _values.Count + 1;

if(!ContainsValue(value)) return 0;

for (int i = start; i < end; i++) {
if (_values[i - 1].Equals(value)) return i;
}
Expand All @@ -235,14 +276,30 @@ public virtual void Cut(int start = 1, int end = 0) {
_associativeValues.Remove(_values[i - 1]);
}

if (end > start)
_values.RemoveRange(start - 1, end - start);
if (end > start) {
var index = start - 1;
var len = end - start;
var elements = _values.GetRange(index, len);

foreach (var element in elements) {
var rlCache = _reverseLookup[element] -= 1;

if (rlCache <= 0) {
_reverseLookup.Remove(element);
}
}

_values.RemoveRange(index, len);
}

UpdateTracyContentsMemory();
}

public void Insert(int index, DreamValue value) {
_values.Insert(index - 1, value);
if (!_reverseLookup.TryAdd(value, 1)) {
_reverseLookup[value] += 1;
}
UpdateTracyContentsMemory();
}

Expand Down Expand Up @@ -652,6 +709,16 @@ public override IEnumerable<DreamValue> EnumerateValues() {
yield return new(verb);
}

public override bool ContainsValue(DreamValue value) {
foreach (var containedVal in EnumerateValues()) {
if (value.Equals(containedVal)) {
return true;
}
}

return false;
}

public override void SetValue(DreamValue key, DreamValue value, bool allowGrowth = false) {
throw new Exception("Cannot set the values of a verbs list");
}
Expand Down Expand Up @@ -716,6 +783,16 @@ public override IEnumerable<DreamValue> EnumerateValues() {
}
}

public override bool ContainsValue(DreamValue value) {
foreach (var containedVal in EnumerateValues()) {
if (value.Equals(containedVal)) {
return true;
}
}

return false;
}

public override void SetValue(DreamValue key, DreamValue value, bool allowGrowth = false) {
throw new Exception("Cannot set the values of a verbs list");
}
Expand Down Expand Up @@ -790,6 +867,16 @@ public override IEnumerable<DreamValue> EnumerateValues() {
}
}

public override bool ContainsValue(DreamValue value) {
foreach (var containedVal in EnumerateValues()) {
if (value.Equals(containedVal)) {
return true;
}
}

return false;
}

public override void Cut(int start = 1, int end = 0) {
_atomManager.UpdateAppearance(_owner, appearance => {
var overlaysList = GetOverlaysList(appearance);
Expand Down Expand Up @@ -907,6 +994,16 @@ public override IEnumerable<DreamValue> EnumerateValues() {
yield return new(visContent);
}

public override bool ContainsValue(DreamValue value) {
foreach (var containedVal in EnumerateValues()) {
if (value.Equals(containedVal)) {
return true;
}
}

return false;
}

public override void Cut(int start = 1, int end = 0) {
int count = _visContents.Count + 1;
if (end == 0 || end > count) end = count;
Expand Down Expand Up @@ -1064,6 +1161,16 @@ public override IEnumerable<DreamValue> EnumerateValues() {
}
}

public override bool ContainsValue(DreamValue value) {
foreach (var containedVal in EnumerateValues()) {
if (value.Equals(containedVal)) {
return true;
}
}

return false;
}

public override void SetValue(DreamValue key, DreamValue value, bool allowGrowth = false) {
if (!value.TryGetValueAsDreamObject<DreamObjectFilter>(out var filterObject) && !value.IsNull)
throw new Exception($"Cannot set value of filter list to {value}");
Expand Down Expand Up @@ -1212,6 +1319,16 @@ public override IEnumerable<DreamValue> EnumerateValues() {
return _imageObjects;
}

public override bool ContainsValue(DreamValue value) {
foreach (var containedVal in EnumerateValues()) {
if (value.Equals(containedVal)) {
return true;
}
}

return false;
}

public override void SetValue(DreamValue key, DreamValue value, bool allowGrowth = false) {
throw new Exception("Cannot write to an index of a client images list");
}
Expand Down Expand Up @@ -1275,6 +1392,16 @@ public override IEnumerable<DreamValue> EnumerateValues() {
return AtomManager.EnumerateAtoms().Select(atom => new DreamValue(atom));
}

public override bool ContainsValue(DreamValue value) {
foreach (var containedVal in EnumerateValues()) {
if (value.Equals(containedVal)) {
return true;
}
}

return false;
}

public override void SetValue(DreamValue key, DreamValue value, bool allowGrowth = false) {
throw new Exception("Cannot set the value of world contents list");
}
Expand Down Expand Up @@ -1318,6 +1445,16 @@ public override IEnumerable<DreamValue> EnumerateValues() {
yield return new(movable);
}

public override bool ContainsValue(DreamValue value) {
foreach (var containedVal in EnumerateValues()) {
if (value.Equals(containedVal)) {
return true;
}
}

return false;
}

public override void SetValue(DreamValue key, DreamValue value, bool allowGrowth = false) {
throw new Exception("Cannot set an index of turf contents list");
}
Expand Down Expand Up @@ -1386,6 +1523,16 @@ public override IEnumerable<DreamValue> EnumerateValues() {
}
}

public override bool ContainsValue(DreamValue value) {
foreach (var containedVal in EnumerateValues()) {
if (value.Equals(containedVal)) {
return true;
}
}

return false;
}

public override void SetValue(DreamValue key, DreamValue value, bool allowGrowth = false) {
throw new Exception("Cannot set an index of area contents list");
}
Expand Down Expand Up @@ -1537,6 +1684,16 @@ public override IEnumerable<DreamValue> EnumerateValues() {
yield return state.GetArguments()[i];
}

public override bool ContainsValue(DreamValue value) {
foreach (var containedVal in EnumerateValues()) {
if (value.Equals(containedVal)) {
return true;
}
}

return false;
}

public override void SetValue(DreamValue key, DreamValue value, bool allowGrowth = false) {
if (!key.TryGetValueAsInteger(out var index))
throw new Exception($"Invalid index into args list: {key}");
Expand Down
Loading