Skip to content

Commit 40515c0

Browse files
authored
Merge pull request #39 from KSP2Community/dev
0.11.0 - Add slotted mixins and an error counter
2 parents f285e61 + 87166ac commit 40515c0

24 files changed

+2701
-2178
lines changed

plugin_template/swinfo.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"name": "Patch Manager",
66
"description": "A mod for generic patching needs similar to KSP 1's Module Manager.",
77
"source": "https://github.com/KSP2Community/PatchManager",
8-
"version": "0.10.1",
8+
"version": "0.11.0",
99
"version_check": "https://raw.githubusercontent.com/KSP2Community/PatchManager/main/plugin_template/swinfo.json",
1010
"ksp2_version": {
1111
"min": "0.2.0",

src/PatchManager.Core/Assets/PatchingManager.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ internal static class PatchingManager
2828
private static Dictionary<string, List<(string name, string text)>> _createdAssets = new();
2929

3030
internal static int TotalPatchCount;
31+
internal static int TotalErrorCount;
32+
3133
public static void GenerateUniverse(HashSet<string> singleFileModIds)
3234
{
3335
var loadedPlugins = PluginList.AllEnabledAndActivePlugins.Select(x => x.Guid).ToList();
@@ -87,6 +89,7 @@ private static string PatchJson(string label, string assetName, string text)
8789
}
8890
catch (Exception e)
8991
{
92+
TotalErrorCount += 1;
9093
Console.WriteLine($"Patch of {label}:{assetName} errored due to: {e}");
9194
text = backup;
9295
}

src/PatchManager.Core/CoreModule.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ public override VisualElement GetDetails()
192192
{
193193
text.text += "Total amount of patches: Unknown (loaded from cache)\n";
194194
}
195+
text.text += $"Total amount of errors: {PatchingManager.TotalErrorCount}\n";
195196

196197
text.text += "Patched labels:";
197198
foreach (var label in PatchingManager.Universe.LoadedLabels)

src/PatchManager.Core/Patches/Runtime/LoadingBarPatch.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public static bool ShuffleLoadingTip(ref LoadingBar __instance)
1717
if (!InjectPatchManagerTips)
1818
return true;
1919
__instance.tipsText.text = $"Patch Manager: {PatchingManager.TotalPatchCount} patches";
20+
if (PatchingManager.TotalErrorCount > 0)
21+
__instance.tipsText.text += $", {PatchingManager.TotalErrorCount} errors";
2022

2123
return false;
2224
}

src/PatchManager.SassyPatching/Execution/Environment.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using JetBrains.Annotations;
2+
using PatchManager.SassyPatching.Nodes;
3+
using PatchManager.SassyPatching.Nodes.Statements.SelectionLevel;
24

35
namespace PatchManager.SassyPatching.Execution;
46

@@ -20,6 +22,16 @@ public class Environment
2022
/// </summary>
2123
public Dictionary<string, DataValue> ScopedValues;
2224

25+
26+
[CanBeNull] private List<Node> _slotActions;
27+
28+
[CanBeNull]
29+
public List<Node> SlotActions
30+
{
31+
get => _slotActions ?? Parent?.SlotActions;
32+
set => _slotActions = value;
33+
}
34+
2335
/// <summary>
2436
/// Creates a new environment
2537
/// </summary>
@@ -76,7 +88,8 @@ public Environment Snapshot()
7688
var parent = Parent?.Snapshot();
7789
return new Environment(GlobalEnvironment, parent)
7890
{
79-
ScopedValues = scopedValues
91+
ScopedValues = scopedValues,
92+
_slotActions = _slotActions
8093
};
8194
}
8295
}
Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using JetBrains.Annotations;
22
using PatchManager.SassyPatching.Exceptions;
33
using PatchManager.SassyPatching.Interfaces;
4+
using PatchManager.SassyPatching.Nodes;
45
using PatchManager.SassyPatching.Nodes.Statements.SelectionLevel;
56
using PatchManager.SassyPatching.Nodes.Statements.TopLevel;
67

@@ -17,48 +18,10 @@ public PatchMixin(Mixin mixin)
1718

1819
public void Include(Environment env, List<PatchArgument> arguments, ISelectable selectable, [CanBeNull] IModifiable modifiable)
1920
{
20-
Environment subEnvironment = new Environment(env.GlobalEnvironment, env);
21+
var subEnvironment = new Environment(env.GlobalEnvironment, env);
2122
foreach (var arg in Function.Arguments)
2223
{
23-
// As per usual we consume
24-
bool foundPositional = false;
25-
DataValue argument = null;
26-
int removalIndex = -1;
27-
for (int i = 0; i < arguments.Count; i++)
28-
{
29-
if (!foundPositional && arguments[i].ArgumentName == null)
30-
{
31-
foundPositional = true;
32-
removalIndex = i;
33-
argument = arguments[i].ArgumentDataValue;
34-
}
35-
36-
if (arguments[i].ArgumentName != arg.Name) continue;
37-
removalIndex = i;
38-
argument = arguments[i].ArgumentDataValue;
39-
break;
40-
}
41-
42-
if (removalIndex >= 0)
43-
{
44-
arguments.RemoveAt(removalIndex);
45-
}
46-
if (argument == null)
47-
{
48-
if (arg.Value != null)
49-
{
50-
subEnvironment[arg.Name] = arg.Value.Compute(subEnvironment);
51-
}
52-
else
53-
{
54-
throw new InvocationException($"No value found for argument: {arg.Name}");
55-
}
56-
}
57-
else
58-
{
59-
// args.Add(CheckParameter(parameter, argument));
60-
subEnvironment[arg.Name] = argument;
61-
}
24+
ConsumeMixinArgument(arguments, arg, subEnvironment);
6225
}
6326

6427
if (arguments.Count > 0)
@@ -78,4 +41,47 @@ public void Include(Environment env, List<PatchArgument> arguments, ISelectable
7841
}
7942

8043
}
44+
45+
private static void ConsumeMixinArgument(List<PatchArgument> arguments, Argument arg, Environment subEnvironment)
46+
{
47+
// As per usual we consume
48+
var foundPositional = false;
49+
DataValue argument = null;
50+
var removalIndex = -1;
51+
for (var i = 0; i < arguments.Count; i++)
52+
{
53+
if (!foundPositional && arguments[i].ArgumentName == null)
54+
{
55+
foundPositional = true;
56+
removalIndex = i;
57+
argument = arguments[i].ArgumentDataValue;
58+
}
59+
60+
if (arguments[i].ArgumentName != arg.Name) continue;
61+
removalIndex = i;
62+
argument = arguments[i].ArgumentDataValue;
63+
break;
64+
}
65+
66+
if (removalIndex >= 0)
67+
{
68+
arguments.RemoveAt(removalIndex);
69+
}
70+
if (argument == null)
71+
{
72+
if (arg.Value != null)
73+
{
74+
subEnvironment[arg.Name] = arg.Value.Compute(subEnvironment);
75+
}
76+
else
77+
{
78+
throw new InvocationException($"No value found for argument: {arg.Name}");
79+
}
80+
}
81+
else
82+
{
83+
// args.Add(CheckParameter(parameter, argument));
84+
subEnvironment[arg.Name] = argument;
85+
}
86+
}
8187
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using PatchManager.SassyPatching.Exceptions;
2+
using PatchManager.SassyPatching.Interfaces;
3+
using Environment = PatchManager.SassyPatching.Execution.Environment;
4+
5+
namespace PatchManager.SassyPatching.Nodes.Statements.SelectionLevel;
6+
7+
/// <summary>
8+
/// Represents a mixin block include (i.e. slotting actions into a mixin)
9+
/// </summary>
10+
public class MixinBlockInclude : Node, ISelectionAction
11+
{
12+
/// <summary>
13+
/// The name of the mixin being included
14+
/// </summary>
15+
public readonly string MixinName;
16+
/// <summary>
17+
/// The list of arguments to the mixin being included
18+
/// </summary>
19+
public readonly List<CallArgument> Arguments;
20+
21+
/// <summary>
22+
/// The actions to be slotted into the mixin
23+
/// </summary>
24+
public readonly List<Node> SlotActions;
25+
26+
internal MixinBlockInclude(Coordinate c, string mixinName, List<CallArgument> arguments, List<Node> slotActions) : base(c)
27+
{
28+
MixinName = mixinName;
29+
Arguments = arguments;
30+
SlotActions = slotActions;
31+
}
32+
33+
/// <inheritdoc />
34+
public override void ExecuteIn(Environment environment)
35+
{
36+
}
37+
38+
/// <inheritdoc />
39+
public void ExecuteOn(Environment environment, ISelectable selectable, IModifiable modifiable)
40+
{
41+
if (environment.GlobalEnvironment.AllMixins.TryGetValue(MixinName, out var mixin))
42+
{
43+
try
44+
{
45+
var subEnv = new Environment(environment.GlobalEnvironment, environment)
46+
{
47+
SlotActions = SlotActions
48+
};
49+
mixin.Include(subEnv,Arguments.Select(x => x.Compute(environment)).ToList(),selectable,modifiable);
50+
}
51+
catch (InvocationException e)
52+
{
53+
throw new InterpreterException(Coordinate, e.ToString());
54+
}
55+
}
56+
else
57+
{
58+
throw new InterpreterException(Coordinate, $"{MixinName} is not a valid mixin");
59+
}
60+
}
61+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using PatchManager.SassyPatching.Exceptions;
2+
using PatchManager.SassyPatching.Interfaces;
3+
using Environment = PatchManager.SassyPatching.Execution.Environment;
4+
5+
namespace PatchManager.SassyPatching.Nodes.Statements.SelectionLevel;
6+
7+
public class MixinSlot(Coordinate c) : Node(c), ISelectionAction
8+
{
9+
public override void ExecuteIn(Environment environment)
10+
{
11+
}
12+
13+
public void ExecuteOn(Environment environment, ISelectable selectable, IModifiable modifiable)
14+
{
15+
var actions = environment.SlotActions;
16+
if (actions == null)
17+
{
18+
throw new InterpreterException(Coordinate, "Attempting to insert into a mixin slot without there being any actions passed for this purpose");
19+
}
20+
21+
foreach (var action in actions)
22+
{
23+
if (action is ISelectionAction selectionAction)
24+
{
25+
selectionAction.ExecuteOn(environment, selectable, modifiable);
26+
}
27+
else
28+
{
29+
action.ExecuteIn(environment);
30+
}
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)