Skip to content

Commit 0891b1e

Browse files
make infrastructure for property setting
1 parent 0110a03 commit 0891b1e

14 files changed

Lines changed: 187 additions & 44 deletions

File tree

Code/ArgumentSystem/Arguments/LooseReferenceArgument.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@ namespace SER.Code.ArgumentSystem.Arguments;
99

1010
public class LooseReferenceArgument(string name, Type type) : Argument(name)
1111
{
12-
private readonly string _validInput = $"a reference to {type.AccurateName} object.";
13-
public override string InputDescription => _validInput;
12+
// rider optimization :tf:
13+
protected string ValidInput
14+
{
15+
get => $"a reference to {field} object.";
16+
} = type != typeof(object) ? type.AccurateName : "any";
17+
18+
public override string InputDescription => ValidInput;
1419

1520
[UsedImplicitly]
1621
public virtual DynamicTryGet<object> GetConvertSolution(BaseToken token)
@@ -30,14 +35,13 @@ public TryGet<object> TryParse(ReferenceValue value, Type targetType)
3035
return value.Value;
3136
}
3237

33-
return $"The {value} reference is not {_validInput}";
38+
return $"The {value} reference is not {ValidInput}";
3439
}
3540
}
3641

3742

3843
public class ReferenceArgument<TValue>(string name) : LooseReferenceArgument(name, typeof(TValue))
3944
{
40-
private static readonly string ValidInput = $"a reference to {typeof(TValue).AccurateName} object.";
4145
public override string InputDescription => ValidInput;
4246

4347
[UsedImplicitly]
@@ -58,6 +62,6 @@ public static TryGet<TValue> TryParse(ReferenceValue value)
5862
return tValue;
5963
}
6064

61-
return $"The {value} reference is not {ValidInput}";
65+
return $"The {value} reference is not valid {typeof(TValue).AccurateName} object";
6266
}
6367
}

Code/ArgumentSystem/Arguments/TextArgument.cs

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,45 +9,36 @@
99

1010
namespace SER.Code.ArgumentSystem.Arguments;
1111

12-
public class TextArgument(string name, bool needsQuotes = true, bool allowsSpaces = true) : Argument(name)
12+
public class TextArgument(string name, bool allowsSpaces = true) : Argument(name)
1313
{
14-
public override string InputDescription => "Any text e.g. \"Hello, World!\""
15-
+ (!needsQuotes ? " (it can be without the quotes)" : "")
16-
+ (!allowsSpaces ? " but it CANNOT contain spaces!" : "");
14+
public override string InputDescription => allowsSpaces
15+
? "Any text e.g. \"Hello, World!\""
16+
: "Text with no spaces and no quotes e.g. someOption";
1717

1818
[UsedImplicitly]
1919
public DynamicTryGet<string> GetConvertSolution(BaseToken token)
2020
{
2121
if (token is TextToken textToken)
2222
{
23-
return new(() => textToken.GetDynamicResolver().Invoke().OnSuccess(SpaceCheck));
23+
return new(() => textToken.GetDynamicResolver().Invoke());
2424
}
2525

2626
if (token is not IValueToken valToken || !valToken.CapableOf<LiteralValue>(out var get))
2727
{
28-
if (!needsQuotes)
28+
if (!allowsSpaces)
2929
{
30-
return SpaceCheck(token.GetBestTextRepresentation(null));
30+
return token.GetBestTextRepresentation(null).AsSuccess();
3131
}
3232

3333
return DynamicTryGet.Error("Value cannot represent text.");
3434
}
3535

3636
if (valToken.IsConstant)
3737
{
38-
return get().OnSuccess(v => SpaceCheck(v.StringRep));
38+
return get().OnSuccess(v => v.StringRep);
3939
}
4040

41-
return new(() => get().OnSuccess(v => SpaceCheck(v.StringRep)));
41+
return new(() => get().OnSuccess(v => v.StringRep));
4242

43-
TryGet<string> SpaceCheck(string value)
44-
{
45-
if (!allowsSpaces && value.Any(char.IsWhiteSpace))
46-
{
47-
return "Value contains spaces, which are not allowed".AsError();
48-
}
49-
50-
return value.AsSuccess();
51-
}
5243
}
5344
}

Code/ArgumentSystem/ProvidedArguments.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ namespace SER.Code.ArgumentSystem;
2323
public class ProvidedArguments(Method method)
2424
{
2525
private Dictionary<(string name, Type type), List<DynamicTryGet>> ArgumentValues { get; } = [];
26+
27+
public Generator[] GetGenerators(string argName)
28+
{
29+
return GetValue<Generator[], GeneratorsArgument>(argName);
30+
}
2631

2732
public T GetVariable<T>(string argName) where T : Variable
2833
{

Code/Helpers/NumericExpressionReslover.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ uint tempId
147147
AppendRaw(token.RawRep);
148148
return true;
149149
}
150+
case { RawRep: "=" }:
150151
case { RawRep: "is" }:
151152
{
152153
AppendRaw("==");

Code/MethodSystem/Methods/CallvoteMethods/VoteOptionMethod.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public record VoteOption(string Option, string DisplayText);
1818

1919
public override Argument[] ExpectedArguments { get; } =
2020
[
21-
new TextArgument("option", allowsSpaces: false)
21+
new TextArgument("option", false)
2222
{
2323
Description = "This will be the command for voting AND the result of the vote, if it wins."
2424
},

Code/Plugin/Commands/HelpSystem/DocsProvider.cs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -602,25 +602,25 @@ public static string GetPropertiesHelpPage()
602602
603603
--- Basic SER value properties ---
604604
605-
PlayerValue:
605+
Player:
606606
- {{playerPropsList}}
607607
608-
CollectionValue:
608+
Collection:
609609
- {{collectionPropsList}}
610610
611-
NumberValue:
611+
Number:
612612
- {{numberPropsList}}
613613
614-
TextValue:
614+
Text:
615615
- {{textPropsList}}
616616
617-
BoolValue:
617+
Bool:
618618
- {{boolPropsList}}
619619
620-
ColorValue:
620+
Color:
621621
- {{colorPropsList}}
622622
623-
DurationValue:
623+
Duration:
624624
- {{durationPropsList}}
625625
626626
--- Registered C# objects ---
@@ -714,25 +714,35 @@ public static bool GetPropertiesForType(string typeName, out string response)
714714
var sortedProps = props.OrderBy(kvp => kvp.Key).ToList();
715715
var custom = sortedProps.Where(p => !p.Value.IsReflected).ToList();
716716
var reflected = sortedProps.Where(p => p.Value.IsReflected).ToList();
717-
718-
sb.AppendLine("\n--- Base properties ---");
719-
foreach (var (name, info) in reflected)
717+
718+
if (reflected.Count > 0)
720719
{
721-
var returnTypeFriendlyName = info.ReturnType.ToString();
722-
sb.AppendLine($"> {name} ({returnTypeFriendlyName}){(string.IsNullOrEmpty(info.Description) ? "" : $" - {info.Description}")}");
720+
sb.AppendLine("\n--- Base properties ---");
721+
foreach (var (name, info) in reflected)
722+
{
723+
sb.AppendLine(GetTypeInfo(name, info));
724+
}
723725
}
724726

725727
if (custom.Count > 0)
726728
{
727729
sb.AppendLine("\n--- Custom SER properties ---");
728730
foreach (var (name, info) in custom)
729731
{
730-
var returnTypeFriendlyName = info.ReturnType.ToString();
731-
sb.AppendLine($"> {name} ({returnTypeFriendlyName}){(string.IsNullOrEmpty(info.Description) ? "" : $" - {info.Description}")}");
732+
sb.AppendLine(GetTypeInfo(name, info));
732733
}
733734
}
734735

735736
response = sb.ToString();
736737
return true;
738+
739+
string GetTypeInfo(string name, IValueWithProperties.PropInfo info)
740+
{
741+
var returnTypeFriendlyName = info.ReturnType.ToString();
742+
return $"> {name} " +
743+
$"({returnTypeFriendlyName}) " +
744+
$"{(info.IsSettable ? "[settable] " : "")}" +
745+
$"{(string.IsNullOrEmpty(info.Description) ? "" : $"- {info.Description}")}";
746+
}
737747
}
738748
}

Code/ValueSystem/CollectionValue.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,45 @@ public override string ToString()
194194
{
195195
return $"[{string.Join(", ", CastedValues.Select(v => v.ToString()))}]";
196196
}
197+
198+
public override TryGet<object> ToCSharpObject(Type targetType)
199+
{
200+
if (targetType.IsInstanceOfType(value)) return TryGet<object>.Success(value);
201+
202+
Type? elementType = null;
203+
if (targetType.IsArray)
204+
{
205+
elementType = targetType.GetElementType();
206+
}
207+
else if (targetType.IsGenericType && (targetType.GetGenericTypeDefinition() == typeof(IEnumerable<>) ||
208+
targetType.GetGenericTypeDefinition() == typeof(List<>) ||
209+
targetType.GetGenericTypeDefinition() == typeof(IList<>) ||
210+
targetType.GetGenericTypeDefinition() == typeof(ICollection<>)))
211+
{
212+
elementType = targetType.GetGenericArguments()[0];
213+
}
214+
215+
if (elementType == null) return $"Cannot convert collection to {targetType.Name}";
216+
217+
var listType = typeof(List<>).MakeGenericType(elementType);
218+
var list = (IList)Activator.CreateInstance(listType);
219+
220+
foreach (var val in CastedValues)
221+
{
222+
var converted = val.ToCSharpObject(elementType);
223+
if (converted.HasErrored(out var error, out var obj)) return error;
224+
list.Add(obj);
225+
}
226+
227+
if (targetType.IsArray)
228+
{
229+
var array = Array.CreateInstance(elementType, list.Count);
230+
list.CopyTo(array, 0);
231+
return TryGet<object>.Success(array);
232+
}
233+
234+
return TryGet<object>.Success(list);
235+
}
197236
}
198237

199238
[UsedImplicitly]

Code/ValueSystem/LiteralValue.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Diagnostics.CodeAnalysis;
22
using JetBrains.Annotations;
33
using SER.Code.Exceptions;
4+
using SER.Code.Helpers.ResultSystem;
45
using SER.Code.ValueSystem.PropertySystem;
56

67
namespace SER.Code.ValueSystem;
@@ -44,6 +45,19 @@ public override string ToString()
4445
}
4546

4647
public override int HashCode => Value.GetHashCode();
48+
49+
public override TryGet<object> ToCSharpObject(Type targetType)
50+
{
51+
if (targetType.IsInstanceOfType(Value)) return Value;
52+
try
53+
{
54+
return Convert.ChangeType(Value, targetType);
55+
}
56+
catch
57+
{
58+
return $"Cannot convert {Value.GetType().Name} to {targetType.Name}";
59+
}
60+
}
4761

4862
[UsedImplicitly]
4963
public new static string FriendlyName = "literal value";

Code/ValueSystem/PlayerValue.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Respawning.NamingRules;
99
using SER.Code.Exceptions;
1010
using SER.Code.Extensions;
11+
using SER.Code.Helpers.ResultSystem;
1112
using SER.Code.ValueSystem.PropertySystem;
1213

1314
namespace SER.Code.ValueSystem;
@@ -226,4 +227,19 @@ private class Info<T>(Func<Player, T> handler, string? description)
226227
[PlayerProperty.UnitId] = new Info<NumberValue>(plr => (decimal)plr.UnitId, null),
227228
[PlayerProperty.Unit] = new Info<TextValue>(plr => NamingRulesManager.ClientFetchReceived(plr.Team, plr.UnitId).ToStaticTextValue(), "Returns the player's unit (e.g FOXTROT-03) if player is NTF or Facility Guard, otherwise returns an empty text value."),
228229
};
230+
231+
public override TryGet<object> ToCSharpObject(Type targetType)
232+
{
233+
if (targetType == typeof(Player))
234+
{
235+
if (Players.Length == 1) return Players[0];
236+
return "Target requires exactly one player, but multiple or none were provided.";
237+
}
238+
239+
if (targetType.IsAssignableFrom(typeof(Player[]))) return TryGet<object>.Success(Players);
240+
if (targetType.IsAssignableFrom(typeof(List<Player>))) return TryGet<object>.Success(Players.ToList());
241+
if (targetType.IsAssignableFrom(typeof(IEnumerable<Player>))) return TryGet<object>.Success(Players.AsEnumerable());
242+
243+
return $"Cannot convert players to {targetType.Name}";
244+
}
229245
}

Code/ValueSystem/PropertySystem/IValueWithProperties.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ public interface IValueWithProperties
88
public abstract class PropInfo
99
{
1010
public abstract TryGet<Value> GetValue(object obj);
11+
public virtual Result SetValue(object obj, Value value) => "This property is read-only.";
1112
public abstract SingleTypeOfValue ReturnType { get; }
1213
public abstract string? Description { get; }
1314
public virtual bool IsReflected => false;
15+
public virtual bool IsSettable => false;
1416
}
1517

1618
public abstract class PropInfo<T> : PropInfo

0 commit comments

Comments
 (0)