Skip to content

Commit 844f65b

Browse files
committed
Add support for GuiControls
1 parent 2113f38 commit 844f65b

9 files changed

Lines changed: 303 additions & 43 deletions

File tree

.gitignore

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
bin/
2-
obj/
3-
/packages/
4-
riderModule.iml
5-
/_ReSharper.Caches/
6-
*.user
7-
.idea/
8-
.vs/
9-
Testing/
1+
bin/
2+
obj/
3+
/packages/
4+
riderModule.iml
5+
/_ReSharper.Caches/
6+
*.user
7+
.idea/
8+
.vs/
9+
Testing/

GS2Engine/Enums/StackEntryType.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public enum StackEntryType
88
Boolean,
99
Array,
1010
ArrayStart,
11-
Player
11+
Player,
12+
Function
1213
}
1314
}

GS2Engine/Extensions/StackEntryExtensions.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using GS2Engine.Enums;
5+
using GS2Engine.GS2.Script;
56
using GS2Engine.Models;
67

78
namespace GS2Engine.Extensions
@@ -50,13 +51,20 @@ private static StackEntryType GetStackEntryType(object stackObject)
5051
return StackEntryType.String;
5152
default:
5253
{
53-
if (stackObject.GetType() == typeof(TString))
54+
Type stackType = stackObject.GetType();
55+
if (stackType == typeof(TString))
5456
return StackEntryType.String;
5557

58+
if (stackType == typeof(Script.Command))
59+
return StackEntryType.Function;
60+
61+
if (stackType.GetInterfaces().Any(x => x.Name.Equals("IGuiControl", StringComparison.CurrentCultureIgnoreCase)))
62+
return StackEntryType.Array;
63+
5664
if (stackObject is float)
5765
return StackEntryType.Number;
5866

59-
if (stackObject.GetType().IsGenericType && stackObject.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>)))
67+
if (stackType.IsGenericType && stackType.GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>)))
6068
return StackEntryType.Array;
6169

6270
throw new ArgumentOutOfRangeException();

GS2Engine/GS2/Script/Script.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class Script
1616
private readonly List<TString> _strings = new();
1717
public readonly Dictionary<string, FunctionParams> Functions = new();
1818
public IDictionary<string, VariableCollection> GlobalObjects = new Dictionary<string, VariableCollection>();
19-
public VariableCollection GlobalVariables = new();
19+
public static VariableCollection GlobalVariables = new();
2020

2121
private ScriptCom[] _bytecode = Array.Empty<ScriptCom>();
2222

@@ -71,7 +71,7 @@ private void Init(IDictionary<string, VariableCollection>? objects, VariableColl
7171
private void Reset()
7272
{
7373
Machine.Reset();
74-
GlobalVariables.Clear();
74+
//GlobalVariables.Clear();
7575
Functions.Clear();
7676
GlobalObjects.Clear();
7777
ExternalFunctions.Clear();

GS2Engine/GS2/Script/ScriptMachine.cs

Lines changed: 109 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Reflection;
45
using System.Threading.Tasks;
56
using GS2Engine.Enums;
67
using GS2Engine.Exceptions;
@@ -33,7 +34,7 @@ public async Task<IStackEntry> Execute(string functionName, Stack<IStackEntry>?
3334
if (!_script.Functions.TryGetValue(functionName.ToLower(), out FunctionParams value))
3435
return 0.ToStackEntry();
3536

36-
Stack<IStackEntry> stack = new();
37+
Stack<IStackEntry>? stack = new();
3738

3839
int desiredStart = value.BytecodePosition;
3940
int index = _firstRun ? 0 : value.BytecodePosition;
@@ -43,14 +44,15 @@ public async Task<IStackEntry> Execute(string functionName, Stack<IStackEntry>?
4344
const int maxLoopCount = 10000;
4445

4546
IStackEntry? opCopy = null;
47+
Stack<IStackEntry> opWith = new();
48+
4649
Tools.DebugLine($"Starting to execute function \"{functionName}\"");
4750
while (index < _script.Bytecode.Length)
4851
{
4952
int curIndex = index;
5053
index = curIndex + 1;
5154
_indexPos = index;
5255

53-
5456
ScriptCom op = _script.Bytecode[curIndex];
5557

5658
Tools.Debug($"OP: {op.OpCode}");
@@ -151,21 +153,42 @@ public async Task<IStackEntry> Execute(string functionName, Stack<IStackEntry>?
151153

152154
break;
153155
case Opcode.OP_CALL:
154-
TString? cmd = getEntryValue<TString>(stack.Pop());
156+
IStackEntry? callEntry = GetEntry(stack.Pop());
157+
object? cmd = getEntryValue<object>(callEntry);
158+
155159
Stack<IStackEntry> parameters = stack.Clone();
156160
stack.Clear();
157-
if (_script.Functions.ContainsKey(cmd?.ToString().ToLower() ?? string.Empty))
158-
stack.Push(await Execute(cmd?.ToString().ToLower() ?? string.Empty, parameters));
159-
else if (Functions.TryGetValue(cmd?.ToString().ToLower() ?? string.Empty, out Script.Command command))
160-
stack.Push(command.Invoke(this, parameters.ToArray()));
161-
else stack.Push(0.ToStackEntry());
161+
switch (callEntry.Type)
162+
{
163+
case StackEntryType.String or Variable when opWith.Any():
164+
stack.Push(opWith?.Peek()?.GetValue<VariableCollection>()?.GetVariable(cmd?.ToString()?.ToLower() ?? string.Empty).GetValue<Script.Command>()?.Invoke(this, parameters.ToArray()) ?? 0.ToStackEntry());
165+
break;
166+
case StackEntryType.String or Variable when _script.Functions.ContainsKey(cmd?.ToString().ToLower() ?? string.Empty):
167+
stack.Push(await Execute(cmd?.ToString().ToLower() ?? string.Empty, parameters));
168+
break;
169+
case StackEntryType.String or Variable when Functions.TryGetValue(
170+
cmd?.ToString().ToLower() ?? string.Empty,
171+
out Script.Command command
172+
):
173+
stack.Push(command.Invoke(this, parameters.ToArray()));
174+
break;
175+
case StackEntryType.String or Variable:
176+
stack.Push(0.ToStackEntry());
177+
break;
178+
case Function:
179+
stack.Push((cmd as Script.Command)?.Invoke(this, parameters.ToArray()) ?? 0.ToStackEntry());
180+
break;
181+
default:
182+
stack.Push(0.ToStackEntry());
183+
break;
184+
}
162185

163186
break;
164187
case Opcode.OP_RET:
165188
IStackEntry ret = 0.ToStackEntry();
166189
if (stack.Count > 0)
167190
ret = stack.Pop();
168-
Tools.DebugLine(JsonConvert.SerializeObject(_script.GlobalVariables.GetDictionary(), Formatting.Indented));
191+
Tools.DebugLine(JsonConvert.SerializeObject(Script.GlobalVariables.GetDictionary(), Formatting.Indented));
169192
return ret;
170193
case Opcode.OP_SLEEP:
171194
double sleep = getEntryValue<double>(stack.Pop());
@@ -210,19 +233,25 @@ public async Task<IStackEntry> Execute(string functionName, Stack<IStackEntry>?
210233
break;
211234

212235
case Opcode.OP_TYPE_TRUE:
236+
stack.Push(true.ToStackEntry());
213237
break;
214238
case Opcode.OP_TYPE_FALSE:
239+
stack.Push(false.ToStackEntry());
215240
break;
216241
case Opcode.OP_TYPE_NULL:
242+
stack.Push(0.ToStackEntry());
217243
break;
218244
case Opcode.OP_PI:
245+
stack.Push(Math.PI.ToStackEntry());
219246
break;
220247
case Opcode.OP_COPY_LAST_OP:
221-
opCopy = stack.Peek();
248+
stack.Push(stack.Peek());
222249
break;
223250
case Opcode.OP_SWAP_LAST_OPS:
224-
if (opCopy != null)
225-
stack.Push(opCopy);
251+
IStackEntry? stackSwap1 = stack.Pop();
252+
IStackEntry? stackSwap2 = stack.Pop();
253+
stack.Push(stackSwap1);
254+
stack.Push(stackSwap2);
226255
break;
227256
case Opcode.OP_INDEX_DEC:
228257
break;
@@ -231,6 +260,7 @@ public async Task<IStackEntry> Execute(string functionName, Stack<IStackEntry>?
231260

232261
double convToFloatVal;
233262
if (test?.GetType() == typeof(TString))
263+
234264
convToFloatVal = double.Parse((TString)test);
235265
else if (test?.GetType() == typeof(bool))
236266
convToFloatVal = (bool)test ? 1 : 0;
@@ -261,7 +291,13 @@ public async Task<IStackEntry> Execute(string functionName, Stack<IStackEntry>?
261291

262292
break;
263293
case Opcode.OP_CONV_TO_OBJECT:
264-
stack.Push(GetEntry(stack.Pop()));
294+
stack.Push(
295+
(opWith.Any()
296+
? opWith?.Peek()
297+
?.GetValue<VariableCollection>()?
298+
.GetVariable(getEntryValue<TString>(stack.Pop())?.ToLower() ?? string.Empty)
299+
: GetEntry(stack.Pop(), Variable))!
300+
);
265301
break;
266302
case Opcode.OP_ARRAY_END:
267303

@@ -284,20 +320,47 @@ public async Task<IStackEntry> Execute(string functionName, Stack<IStackEntry>?
284320
case Opcode.OP_MAKEVAR:
285321
break;
286322
case Opcode.OP_NEW_OBJECT:
323+
IStackEntry? newObject = stack.Pop();
324+
IStackEntry? newObjectParam = stack.Pop();
325+
try
326+
{
327+
VariableCollection? newObjectRet = (VariableCollection)GetInstance(
328+
getEntryValue<TString>(newObject) ?? string.Empty,
329+
getEntryValue<object>(newObjectParam)?.ToString()!
330+
)!;
331+
stack.Push(newObjectRet?.ToStackEntry() ?? 0.ToStackEntry());
332+
}
333+
catch (Exception e)
334+
{
335+
stack.Push(0.ToStackEntry());
336+
}
337+
287338
break;
288339
case Opcode.OP_INLINE_CONDITIONAL:
289340
break;
290341
case Opcode.OP_ASSIGN:
291342
IStackEntry val = stack.Pop();
292343

293344
IStackEntry variable = (stack.Count == 0?opCopy:GetEntry(stack.Pop())) ?? 0.ToStackEntry();
294-
if (variable.Type != Variable)
345+
/*if (variable.Type != Variable)
295346
{
296347
variable.SetValue(val.GetValue());
348+
}*/
349+
if (opWith.Any())
350+
{
351+
try
352+
{
353+
opWith?.Peek()?.GetValue<VariableCollection>()?
354+
.AddOrUpdate((variable.GetValue() ?? "").ToString().ToLower(), val);
355+
}
356+
catch (Exception e)
357+
{
358+
Tools.DebugLine(e.Message);
359+
}
297360
}
298361
else if (!_useTemp)
299362
{
300-
_script.GlobalVariables.AddOrUpdate((variable.GetValue() ?? "").ToString().ToLower(), val);
363+
Script.GlobalVariables.AddOrUpdate((variable.GetValue() ?? "").ToString().ToLower(), val);
301364
}
302365
else
303366
{
@@ -327,12 +390,18 @@ public async Task<IStackEntry> Execute(string functionName, Stack<IStackEntry>?
327390
break;
328391
case Opcode.OP_INC:
329392
IStackEntry incVar = GetEntry(stack.Pop());
330-
if (incVar.Type == Number) incVar.SetValue((double?)incVar.GetValue() + 1);
393+
double incVal = getEntryValue<double>(stack.Pop());
394+
if (incVar.Type == Number) incVar.SetValue(incVal + 1);
331395

332396
stack.Push(((double?)incVar.GetValue())?.ToStackEntry() ?? 0.ToStackEntry());
333397

334398
break;
335399
case Opcode.OP_DEC:
400+
IStackEntry decVar = GetEntry(stack.Pop());
401+
double decVal = getEntryValue<double>(stack.Pop());
402+
if (decVar.Type == Number) decVar.SetValue(decVal - 1);
403+
404+
stack.Push(((double?)decVar.GetValue())?.ToStackEntry() ?? 0.ToStackEntry());
336405
break;
337406
case Opcode.OP_ADD:
338407
double addA = getEntryValue<double>(stack.Pop());
@@ -525,13 +594,15 @@ public async Task<IStackEntry> Execute(string functionName, Stack<IStackEntry>?
525594
case Opcode.OP_ARRAY_NEW_MULTIDIM:
526595
break;
527596
case Opcode.OP_WITH:
597+
opWith.Push(stack.Pop());
528598
break;
529599
case Opcode.OP_WITHEND:
600+
stack.Push(opWith.Pop());
530601
break;
531602
case Opcode.OP_FOREACH:
532603
break;
533604
case Opcode.OP_THIS:
534-
stack.Push(new StackEntry(StackEntryType.Array, _script.GlobalVariables));
605+
stack.Push(new StackEntry(StackEntryType.Array, Script.GlobalVariables));
535606
break;
536607
case Opcode.OP_THISO:
537608
break;
@@ -561,18 +632,35 @@ public async Task<IStackEntry> Execute(string functionName, Stack<IStackEntry>?
561632
return 0.ToStackEntry();
562633
}
563634

635+
private static object? GetInstance(string? strFullyQualifiedName, string arg)
636+
{
637+
if (string.IsNullOrEmpty(strFullyQualifiedName)) return null;
638+
Type? type = Type.GetType(strFullyQualifiedName);
639+
if (type != null)
640+
return Activator.CreateInstance(type, arg);
641+
foreach (Assembly? asm in AppDomain.CurrentDomain.GetAssemblies())
642+
{
643+
type = asm.GetTypes().FirstOrDefault(x => x.Name.Equals(strFullyQualifiedName, StringComparison.CurrentCultureIgnoreCase)) ?? null;
644+
if (type != null)
645+
return Activator.CreateInstance(type, arg);
646+
}
647+
return null;
648+
}
564649
public IStackEntry GetEntry(IStackEntry stackEntry, StackEntryType? overrideStackType = null)
565650
{
566651
StackEntryType? type = overrideStackType ?? stackEntry.Type;
567652
switch (type)
568653
{
569654
case Variable
570-
when _tempVariables.ContainsVariable(stackEntry.GetValue<TString>()?.ToLower() ?? string.Empty):
655+
when _tempVariables.ContainsVariable(stackEntry.GetValue()?.ToString()?.ToLower() ?? string.Empty):
571656
_useTemp = false;
572-
return _tempVariables.GetVariable(stackEntry.GetValue<TString>()?.ToLower() ?? string.Empty);
657+
return _tempVariables.GetVariable(stackEntry.GetValue()?.ToString()?.ToLower() ?? string.Empty);
658+
case Variable
659+
when Script.GlobalVariables.ContainsVariable(stackEntry.GetValue()?.ToString()?.ToLower() ?? string.Empty):
660+
return Script.GlobalVariables[stackEntry.GetValue()?.ToString()?.ToLower()?? string.Empty];
573661
case Variable
574-
when _script.GlobalVariables.ContainsVariable(stackEntry.GetValue<TString>()?.ToLower() ?? string.Empty):
575-
return _script.GlobalVariables[stackEntry.GetValue<TString>()?.ToLower() ?? string.Empty];
662+
when _script.GlobalObjects.ContainsKey(stackEntry.GetValue()?.ToString()?.ToLower()?? string.Empty):
663+
return _script.GlobalObjects[stackEntry.GetValue()?.ToString()?.ToLower() ?? string.Empty].ToStackEntry();
576664
default:
577665
return stackEntry;
578666
}

GS2Engine/GS2Engine.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
</PropertyGroup>
1818

1919
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
20-
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
20+
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
2121
</PropertyGroup>
2222

2323
<ItemGroup>

GS2Engine/Models/Control.cs

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)