-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathProgram.cs
More file actions
316 lines (262 loc) · 8.35 KB
/
Program.cs
File metadata and controls
316 lines (262 loc) · 8.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
using Sandbox.ModAPI.Ingame;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VRage.Game.ModAPI.Ingame.Utilities;
namespace IngameScript
{
// ReSharper disable once ClassNeverInstantiated.Global
public partial class Program : MyGridProgram
{
#region mdk preserve
#region mdk macros
// Last Build: $MDK_DATETIME$
#endregion
#endregion
/* -----------------------------------------------------------
* -- User Editable Variables --
* ----------------------------------------------------------- */
/// <summary>
/// Default Retraction Speed
/// Speed (in m/s) when not otherwise defined
/// </summary>
private readonly float defaultRetractSpeed = 0.5f;
/// <summary>
/// Default Extension Speed
/// Speed (in m/s) when not otherwise defined
/// </summary>
private readonly float defaultExtendSpeed = 0.5f;
/// <summary>
/// Default - Auto Retract
/// Set if not otherwise defined
/// </summary>
private readonly bool defaultAutoRetract = false;
/// <summary>
/// Default - Auto Extend
/// Set if not otherwise defined
/// </summary>
private readonly bool defaultAutoExtend = false;
/* -----------------------------------------------------------
* -- Do Not Edit Below This Line! --
* ----------------------------------------------------------- */
/// <summary>
/// Instance to the INI system
/// </summary>
// ReSharper disable once InconsistentNaming
private static readonly MyIni ini = new MyIni();
/// <summary>
/// The [section] to be read from in Custom Data
/// </summary>
private static readonly string SectionKey = "Piston Settings";
/// <summary>
/// List of commands our program will respond too via the arguments box
/// </summary>
private readonly Dictionary<string, Action> commands = new Dictionary<string, Action>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// This is the programs output to be printed on the programmable block pane
/// </summary>
private readonly StringBuilder outputText;
/// <summary>
/// Container for storing various speeds in addition to the piston
/// </summary>
private struct PistonData
{
public bool AutoRetract;
public bool AutoExtend;
public float RetractSpeed;
public float ExtendSpeed;
public IMyPistonBase Piston;
}
/// <summary>
/// Linked list storing our affected pistons, as well as the various speeds
/// </summary>
private readonly List<PistonData> pistonDataList;
/// <summary>
/// The last message to be displayed, this allows persistence along with an activity indicator
/// </summary>
private readonly StringBuilder lastMessageText;
/// <summary>
/// Our program constructor
/// This is run on compilation (world load, script import, etc)
/// </summary>
public Program()
{
// Command list
commands["reset"] = Init;
// property initializers
pistonDataList = new List<PistonData>();
outputText = new StringBuilder();
lastMessageText = new StringBuilder();
__activityIndicator = 0;
// Run frequency
Runtime.UpdateFrequency = UpdateFrequency.Once;
}
/// <summary>
/// The program entry-point.
/// </summary>
/// <param name="arguments">The string supplied by the user</param>
/// <param name="updateSource">The source of this update, whether by the user, a timer, or continous running</param>
public void Main(string arguments, UpdateType updateSource)
{
outputText.Clear();
outputText.AppendFormat(
"-- Configurable Pistons --" +
"\n" +
" Pistons Monitored: {0:d}" +
"\n" +
"\n" +
" - Stats -\n" +
" Runtime {0:F3} ms every {1:F0} ms\n" +
"\n",
pistonDataList.Count(),
Runtime.LastRunTimeMs,
Runtime.TimeSinceLastRun.TotalMilliseconds
);
// Handing user input
if (updateSource == UpdateType.Terminal) {
MyCommandLine commandLine = new MyCommandLine();
if (commandLine.TryParse(arguments)) {
string command = commandLine.Argument(0);
Action commandAction;
if (commands.TryGetValue(command, out commandAction)) {
SetMessage("Executing: {0:s}", command);
commandAction();
}
else {
StringBuilder msg = new StringBuilder();
msg.AppendFormat(
" Unknown Command: {0:s}\n" +
"\n" +
" Available Commands:\n" +
" reset Reload settings\n",
command
);
SetMessage(msg.ToString());
msg.Clear();
}
}
}
else if ((updateSource & UpdateType.Update10) != 0) {
foreach (PistonData data in pistonDataList) {
// skip if the block no longer exists in the world
if (data.Piston.Closed) {
if (pistonDataList.Remove(data)) {
SetMessage("A Piston was removed from grid\nDeleted Reference.");
}
break;
}
// Skip if powered off or in a non-functional state
if (!data.Piston.IsWorking) {
continue;
}
switch (data.Piston.Status) {
case PistonStatus.Extended:
data.Piston.Velocity = data.AutoRetract ? -data.RetractSpeed : data.RetractSpeed;
break;
case PistonStatus.Extending:
data.Piston.Velocity = data.ExtendSpeed;
break;
case PistonStatus.Retracted:
data.Piston.Velocity = data.AutoExtend ? data.ExtendSpeed : -data.ExtendSpeed;
break;
case PistonStatus.Retracting:
data.Piston.Velocity = -data.RetractSpeed;
break;
}
}
// no pistons controlled, stop continuously running
if (pistonDataList.Count == 0) {
Runtime.UpdateFrequency = UpdateFrequency.None;
}
}
else if ((updateSource & UpdateType.Once) != 0) {
// Initialization - Populate the Lists
Init();
if (pistonDataList.Count > 0) {
Runtime.UpdateFrequency = UpdateFrequency.Update10;
}
}
outputText.AppendStringBuilder(lastMessageText);
outputText.AppendLine();
outputText.Append(GetActivityIndicator());
Print(outputText.ToString());
}
/// <summary>
/// Setup our internal list of pistons and associated data
/// </summary>
private void Init()
{
pistonDataList.Clear();
// temporary list
List<IMyPistonBase> pistonList = new List<IMyPistonBase>();
GridTerminalSystem.GetBlocksOfType<IMyPistonBase>(pistonList, piston => MyIni.HasSection(piston.CustomData, SectionKey));
foreach (IMyPistonBase piston in pistonList) {
if (!ini.TryParse(piston.CustomData, SectionKey)) {
continue;
}
PistonData data = new PistonData {
Piston = piston,
RetractSpeed = ini.Get(SectionKey, "RetractSpeed").ToSingle(defaultRetractSpeed),
ExtendSpeed = ini.Get(SectionKey, "ExtendSpeed").ToSingle(defaultExtendSpeed),
AutoRetract = ini.Get(SectionKey, "AutoRetract").ToBoolean(defaultAutoRetract),
AutoExtend = ini.Get(SectionKey, "AutoExtend").ToBoolean(defaultAutoExtend)
};
pistonDataList.Add(data);
}
pistonList.Clear();
SetMessage("Piston cache updated...");
}
private void SetMessage(string message)
{
lastMessageText.Clear();
lastMessageText.AppendFormat("\n - Message -\n{0}\n\n", message);
}
private void SetMessage(string format, params object[] args)
{
lastMessageText.Clear();
lastMessageText.AppendFormat(format, args);
}
// ReSharper disable once UnusedMember.Local
private void ClearMessage()
{
lastMessageText.Clear();
}
/// <summary>
/// This is an internal counter for the little . .. ... .... indicator
/// </summary>
// ReSharper disable once InconsistentNaming
private int __activityIndicator;
/// <summary>
/// This is the internal string array for the indicator
/// </summary>
// ReSharper disable once InconsistentNaming
private readonly string[] __indicators = { " ", ". ", " . ", " . ", " .", };
/// <summary>
/// Returns an ever changing string to let the user know the script is "working"
/// </summary>
/// <returns>An ever changing string</returns>
private string GetActivityIndicator()
{
if (__activityIndicator >= __indicators.Length) {
__activityIndicator = 0;
}
return __indicators[__activityIndicator++];
}
/// <summary>
/// Print a message to the message pane
/// </summary>
/// <param name="message">The string to print</param>
private void Print(string message)
{
Echo(message);
}
private void Print(string message, IMyTextSurface surface)
{
if (surface != null) {
surface.WriteText(message);
}
Echo(message);
}
}
}