From 9d136617a951c40279cb4198f12b2a66f01b006d Mon Sep 17 00:00:00 2001 From: wixoaGit Date: Mon, 17 Nov 2025 22:46:50 -0500 Subject: [PATCH 1/2] Add support for named filters --- OpenDreamRuntime/Objects/Types/DreamList.cs | 64 +++++++++++-------- OpenDreamRuntime/Procs/DMProc.cs | 4 +- .../Procs/Native/DreamProcNativeRoot.cs | 1 + OpenDreamShared/Dream/DreamFilter.cs | 5 +- 4 files changed, 46 insertions(+), 28 deletions(-) diff --git a/OpenDreamRuntime/Objects/Types/DreamList.cs b/OpenDreamRuntime/Objects/Types/DreamList.cs index cb69037c93..8bd7e946d9 100644 --- a/OpenDreamRuntime/Objects/Types/DreamList.cs +++ b/OpenDreamRuntime/Objects/Types/DreamList.cs @@ -6,7 +6,6 @@ using OpenDreamRuntime.Rendering; using OpenDreamShared.Dream; using Robust.Server.GameStates; -using Robust.Shared.Serialization.Manager; using Dependency = Robust.Shared.IoC.DependencyAttribute; namespace OpenDreamRuntime.Objects.Types; @@ -980,19 +979,9 @@ public override int FindValue(DreamValue value, int start = 1, int end = 0) { // atom.filters list // Operates on an object's appearance -public sealed class DreamFilterList : DreamList { - [Dependency] private readonly AtomManager _atomManager = default!; - [Dependency] private readonly ISerializationManager _serializationManager = default!; - - private readonly DreamObject _owner; - - public DreamFilterList(DreamObjectDefinition listDef, DreamObject owner) : base(listDef, 0) { - IoCManager.InjectDependencies(this); - _owner = owner; - } - +public sealed class DreamFilterList(DreamObjectDefinition listDef, DreamObject owner) : DreamList(listDef, 0) { public override void Cut(int start = 1, int end = 0) { - _atomManager.UpdateAppearance(_owner, appearance => { + AtomManager.UpdateAppearance(owner, appearance => { int filterCount = appearance.Filters.Count + 1; if (end == 0 || end > filterCount) end = filterCount; @@ -1003,7 +992,7 @@ public override void Cut(int start = 1, int end = 0) { public int GetIndexOfFilter(DreamFilter filter) { ImmutableAppearance appearance = GetAppearance(); int i = 0; - while(i < appearance.Filters.Length) { + while (i < appearance.Filters.Length) { if(appearance.Filters[i] == filter) return i; i++; @@ -1012,8 +1001,20 @@ public int GetIndexOfFilter(DreamFilter filter) { return -1; } + public int GetIndexOfFilter(string filterName) { + ImmutableAppearance appearance = GetAppearance(); + int i = 0; + while (i < appearance.Filters.Length) { + if(appearance.Filters[i].FilterName == filterName) + return i; + i++; + } + + return -1; + } + public void SetFilter(int index, DreamFilter? filter) { - _atomManager.UpdateAppearance(_owner, appearance => { + AtomManager.UpdateAppearance(owner, appearance => { if (index < 1 || index > appearance.Filters.Count) throw new Exception($"Cannot index {index} on filter list"); @@ -1031,8 +1032,16 @@ public void SetFilter(int index, DreamFilter? filter) { } public override DreamValue GetValue(DreamValue key) { - if (!key.TryGetValueAsInteger(out var filterIndex) || filterIndex < 1) + int filterIndex; + if (key.TryGetValueAsString(out var filterName)) { + filterIndex = GetIndexOfFilter(filterName) + 1; // We're 1-indexed while GetIndexOfFilter() is not + } else { + key.TryGetValueAsInteger(out filterIndex); + } + + if (filterIndex < 1) { // The key failed to resolve to a valid index throw new Exception($"Invalid index into filter list: {key}"); + } ImmutableAppearance appearance = GetAppearance(); if (filterIndex > appearance.Filters.Length) @@ -1077,23 +1086,28 @@ public override void AddValue(DreamValue value) { //This is dynamic to prevent the compiler from optimising the SerializationManager.CreateCopy() call to the DreamFilter type //so we can preserve the subclass information. Setting it to DreamFilter instead will cause filter parameters to stop working. dynamic filter = filterObject.Filter; - DreamFilter copy = _serializationManager.CreateCopy(filter, notNullableOverride: true); // Adding a filter creates a copy + DreamFilter copy = SerializationManager.CreateCopy(filter, notNullableOverride: true); // Adding a filter creates a copy DreamObjectFilter.FilterAttachedTo[copy] = this; - _atomManager.UpdateAppearance(_owner, appearance => { + AtomManager.UpdateAppearance(owner, appearance => { appearance.Filters.Add(copy); }); } public override void RemoveValue(DreamValue value) { - if (!value.TryGetValueAsDreamObject(out var filterObject)) - return; + int filterIndex = -1; + if (value.TryGetValueAsString(out var filterName)) { // You can also do atom.filters -= "name" + filterIndex = GetIndexOfFilter(filterName); + } else if (value.TryGetValueAsDreamObject(out var filterObject)) { + filterIndex = GetIndexOfFilter(filterObject.Filter); + } - var filter = filterObject.Filter; + if (filterIndex < 0) // Failed to find the filter in the list + return; - DreamObjectFilter.FilterAttachedTo.Remove(filter); - _atomManager.UpdateAppearance(_owner, appearance => { - appearance.Filters.Remove(filter); + AtomManager.UpdateAppearance(owner, appearance => { + DreamObjectFilter.FilterAttachedTo.Remove(appearance.Filters[filterIndex]); + appearance.Filters.RemoveAt(filterIndex); }); } @@ -1106,7 +1120,7 @@ public override int FindValue(DreamValue value, int start = 1, int end = 0) { } private ImmutableAppearance GetAppearance() { - ImmutableAppearance? appearance = _atomManager.MustGetAppearance(_owner); + ImmutableAppearance? appearance = AtomManager.MustGetAppearance(owner); if (appearance == null) throw new Exception("Atom has no appearance"); diff --git a/OpenDreamRuntime/Procs/DMProc.cs b/OpenDreamRuntime/Procs/DMProc.cs index ea89db1945..b9244b9416 100644 --- a/OpenDreamRuntime/Procs/DMProc.cs +++ b/OpenDreamRuntime/Procs/DMProc.cs @@ -1076,7 +1076,7 @@ public DreamProcArguments CreateProcArguments(ReadOnlySpan values, D string argumentName = key.MustGetValueAsString(); int argumentIndex = proc.ArgumentNames.IndexOf(argumentName); if (argumentIndex == -1) - throw new Exception($"{proc} has no argument named {argumentName}"); + throw new Exception($"{proc} has no argument named \"{argumentName}\""); arguments[argumentIndex] = value; } @@ -1110,7 +1110,7 @@ public DreamProcArguments CreateProcArguments(ReadOnlySpan values, D int argumentIndex = proc.ArgumentNames.IndexOf(argumentName); if (argumentIndex == -1) - throw new Exception($"{proc} has no argument named {argumentName}"); + throw new Exception($"{proc} has no argument named \"{argumentName}\""); arguments[argumentIndex] = argList.GetValue(value); } else { //Ordered argument diff --git a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs index 9bbd9f2695..adfb450ee3 100644 --- a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs +++ b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs @@ -792,6 +792,7 @@ public static DreamValue NativeProc_file2text(NativeProc.Bundle bundle, DreamObj [DreamProc("filter")] [DreamProcParameter("type", Type = DreamValueTypeFlag.String)] // Must be from a valid list + [DreamProcParameter("name", Type = DreamValueTypeFlag.String)] [DreamProcParameter("size", Type = DreamValueTypeFlag.Float)] [DreamProcParameter("color", Type = DreamValueTypeFlag.String)] [DreamProcParameter("x", Type = DreamValueTypeFlag.Float)] diff --git a/OpenDreamShared/Dream/DreamFilter.cs b/OpenDreamShared/Dream/DreamFilter.cs index 93dce06cf0..d943cb5e7d 100644 --- a/OpenDreamShared/Dream/DreamFilter.cs +++ b/OpenDreamShared/Dream/DreamFilter.cs @@ -17,9 +17,12 @@ public partial record DreamFilter { /// public bool Used = false; - [ViewVariables, DataField("type")] + [ViewVariables(VVAccess.ReadOnly), DataField("type")] public string FilterType; + [ViewVariables(VVAccess.ReadOnly), DataField("name")] + public string? FilterName; + public static Type? GetType(string filterType) { return filterType switch { "alpha" => typeof(DreamFilterAlpha), From c40ac886e68b97fc773b7e8844071046120f680d Mon Sep 17 00:00:00 2001 From: wixoaGit Date: Wed, 19 Nov 2025 00:47:40 -0500 Subject: [PATCH 2/2] These are just for loops actually --- OpenDreamRuntime/Objects/Types/DreamList.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/OpenDreamRuntime/Objects/Types/DreamList.cs b/OpenDreamRuntime/Objects/Types/DreamList.cs index 3c81476db6..737bd22083 100644 --- a/OpenDreamRuntime/Objects/Types/DreamList.cs +++ b/OpenDreamRuntime/Objects/Types/DreamList.cs @@ -991,11 +991,9 @@ public override void Cut(int start = 1, int end = 0) { public int GetIndexOfFilter(DreamFilter filter) { ImmutableAppearance appearance = GetAppearance(); - int i = 0; - while (i < appearance.Filters.Length) { - if(appearance.Filters[i] == filter) + for (int i = 0; i < appearance.Filters.Length; i++) { + if (appearance.Filters[i] == filter) return i; - i++; } return -1; @@ -1003,11 +1001,9 @@ public int GetIndexOfFilter(DreamFilter filter) { public int GetIndexOfFilter(string filterName) { ImmutableAppearance appearance = GetAppearance(); - int i = 0; - while (i < appearance.Filters.Length) { - if(appearance.Filters[i].FilterName == filterName) + for (int i = 0; i < appearance.Filters.Length; i++) { + if (appearance.Filters[i].FilterName == filterName) return i; - i++; } return -1;