Skip to content

Commit a50fa9d

Browse files
committed
More Improvements to LuaVM
1 parent b6703d3 commit a50fa9d

File tree

2 files changed

+52
-48
lines changed

2 files changed

+52
-48
lines changed

lib/scripting/lua.context.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
part of 'lua.dart';
2+
3+
class LuaContext {
4+
String pid;
5+
final String script;
6+
final Stopwatch stopwatch = Stopwatch();
7+
final Map<String, SInterface> objects = {};
8+
LuaContext({String? pid, required this.script}) : pid = pid ?? generateUUID();
9+
10+
void start() => stopwatch.start();
11+
}

lib/scripting/lua.dart

Lines changed: 41 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import 'package:lua_dardo_async/lua.dart';
1414
import 'interfaces.dart' as portal;
1515
import 'package:web_socket_channel/web_socket_channel.dart';
1616

17+
part 'lua.context.dart';
18+
1719
typedef LuaArgs = ({List positional, Map named});
1820
typedef LuaResult = ({
1921
dynamic result,
@@ -28,22 +30,12 @@ class Lua {
2830

2931
final WebSocketChannel? socket;
3032

31-
final Set<Stopwatch> _stopwatches = {};
32-
33-
final Map<LuaState, String?> _processIds = {};
34-
35-
static final Map<LuaState, String> _loadedScripts = {};
33+
final Map<LuaState, LuaContext> _contexts = {};
3634

3735
SContract? contract;
3836

3937
Lua({this.socket, this.contract});
4038

41-
/// A map of all objects in the lua state.
42-
///
43-
/// When pushing a object to the stack, an unique hash is generated and
44-
/// a duplicate of the SInterface with the object as its value is added to this map.
45-
final Map<LuaState, Map<String, SInterface>> _objects = {};
46-
4739
static final Map<String, String> classHashes = {};
4840

4941
/// A set of all interfaces in the lua state.
@@ -128,15 +120,14 @@ class Lua {
128120
}
129121

130122
for (int row = 0; row < lines.length; row++) {
131-
final funcReplacements =
132-
functionReplacements.where((r) => r.$1 == row);
133123
final line = lines[row];
134124
String replacedLine = line;
135125
int calDeficit() => replacedLine.length - line.length;
136-
for (final replacement in funcReplacements) {
126+
for (final replacement
127+
in functionReplacements.where((r) => r.$1 == row)) {
137128
final match = replacement.$2;
138129
final funcName = match.group(2)!;
139-
if (!localFuncs.contains(funcName)) {
130+
if (!localFuncs.any((f) => f == funcName)) {
140131
final col = match.start;
141132
if (match.group(3) == null) {
142133
replacedLine = replacedLine.replaceRange(
@@ -158,6 +149,13 @@ class Lua {
158149
},
159150
];
160151

152+
LuaContext getContext(LuaState state) => _contexts[state]!;
153+
154+
void newContext(LuaState state, String script) =>
155+
_contexts[state] = LuaContext(script: script);
156+
157+
void removeContext(LuaState state) => _contexts.remove(state);
158+
161159
/// Initializes the lua state.
162160
/// This includes opening all libraries and adding all enums and statics to the global table.
163161
Future<void> _init(LuaState state) async {
@@ -217,16 +215,14 @@ class Lua {
217215
/// This will push the table to the stack and then set the global with the given name.
218216
Future<void> addGlobal(LuaState state, String name, dynamic value,
219217
{Map<String, dynamic>? metatable}) async {
220-
await _pushToStack(state, value);
221-
if (metatable != null) {
222-
await _applyMetatableToTop(state, metatable);
223-
}
218+
await _pushToStack(state, value, metatable: metatable);
224219
await state.setGlobal(name);
225220
}
226221

227-
SInterface? getObject(LuaState state, String hash) => _objects[state]?[hash];
222+
SInterface? getObject(LuaState state, String hash) =>
223+
getContext(state).objects[hash];
228224
void _setObject(LuaState state, String hash, SInterface interface_) =>
229-
_objects[state]![hash] = interface_;
225+
getContext(state).objects[hash] = interface_;
230226

231227
/// Applies a metatable to the top of the stack.
232228
///
@@ -261,11 +257,12 @@ class Lua {
261257
}
262258

263259
throw ReyveldCallException(message,
264-
traceback: Traceback(getLoadedScript(state), row, col));
260+
traceback: Traceback(lua.getContext(state).script, row, col));
265261
}
266262

267263
/// Pushes a value to the stack.
268-
Future<void> _pushToStack(LuaState state, dynamic value) async {
264+
Future<void> _pushToStack(LuaState state, dynamic value,
265+
{Map<String, dynamic>? metatable}) async {
269266
Reyveld.talker.verbose("Pushing $value to stack.");
270267
if (value is Undefined) {
271268
// Reyveld.talker.verbose("Pushing undefined to stack.");
@@ -331,7 +328,7 @@ class Lua {
331328
int row = finalArgs.removeAt(0);
332329
int col = finalArgs.removeAt(0);
333330

334-
final trackback = Traceback(getLoadedScript(state), row, col);
331+
final trackback = Traceback(getContext(state).script, row, col);
335332

336333
Map namedArgs = {};
337334

@@ -448,6 +445,9 @@ class Lua {
448445
} else {
449446
Reyveld.talker.error("Could not push to stack: $value");
450447
}
448+
if (metatable != null) {
449+
await _applyMetatableToTop(state, metatable);
450+
}
451451
}
452452

453453
/// Gets a value from the top of the stack.
@@ -543,10 +543,10 @@ class Lua {
543543
}
544544

545545
/// Gets the Process ID of the lua state.
546-
String? getPID(LuaState state) => _processIds[state];
546+
String? getPID(LuaState state) => getContext(state).pid;
547547

548548
/// Sets the Process ID of the lua state.
549-
void setPID(LuaState state, String? pid) => _processIds[state] = pid;
549+
void setPID(LuaState state, String pid) => getContext(state).pid = pid;
550550

551551
/// Compiles a lua project.
552552
Future<String> _compile(String entrypoint) async {
@@ -600,7 +600,7 @@ class Lua {
600600
}
601601

602602
Future<void> awaitForCompletion() async {
603-
while (_stopwatches.any((stopwatch) => stopwatch.isRunning)) {
603+
while (_contexts.values.any((e) => e.stopwatch.isRunning)) {
604604
await Future.delayed(Duration(milliseconds: 10));
605605
}
606606
}
@@ -625,18 +625,13 @@ class Lua {
625625
626626
while (_removeQueue.isNotEmpty) {
627627
final state = _removeQueue.removeFirst();
628-
_objects.remove(state);
628+
removeContext(state);
629629
}
630-
final stopwatch = Stopwatch();
631-
_stopwatches.add(stopwatch);
632-
stopwatch.start();
633630
final code = await _compile(entrypoint).then((value) => value.trim());
634631
Reyveld.talker.verbose("Compiled code:\n$code");
635632
final state = LuaState.newState();
636633

637-
_processIds[state] = null;
638-
_objects[state] = {};
639-
_loadedScripts[state] = entrypoint;
634+
newContext(state, entrypoint);
640635

641636
await _init(state);
642637

@@ -649,37 +644,40 @@ class Lua {
649644

650645
final thread = state.loadString(code);
651646

647+
final context = getContext(state);
648+
652649
if (thread != ThreadStatus.luaOk) {
653650
state.error();
651+
context.stopwatch.stop();
654652
return (
655653
result: null,
656-
processTime: stopwatch,
657-
processId: _processIds[state]
654+
processTime: context.stopwatch,
655+
processId: context.pid
658656
);
659657
}
660658
// Run the lua code and see if it was successful
661659
final successful = await state.pCall(0, 1, 0) == ThreadStatus.luaOk;
662-
stopwatch.stop();
660+
context.stopwatch.stop();
663661
_removeQueue.add(state);
664662
if (!successful) {
665663
/// If it wasn't successful, print the error and return null
666-
Reyveld.talker.error("Objects: ${_objects[state]}");
664+
Reyveld.talker.error("Objects: ${context.objects}");
667665
state.error();
668-
stopwatch.stop();
666+
context.stopwatch.stop();
669667
_removeQueue.add(state);
670668
return (
671669
result: null,
672-
processTime: stopwatch,
673-
processId: _processIds[state]
670+
processTime: context.stopwatch,
671+
processId: context.pid
674672
);
675673
}
676674

677675
/// If it was successful, return the result.
678676
final result = await getFromTop(state);
679677
return (
680678
result: result,
681-
processTime: stopwatch,
682-
processId: _processIds[state]
679+
processTime: context.stopwatch,
680+
processId: context.pid
683681
);
684682
}
685683

@@ -763,11 +761,6 @@ ${enum_.key} = {
763761
}
764762
return formattedEnums.join("\n\n");
765763
}
766-
767-
static String getLoadedScript(LuaState state) {
768-
Reyveld.talker.verbose("Getting script.");
769-
return _loadedScripts[state] ?? "";
770-
}
771764
}
772765

773766
/// A reference to a lua function.

0 commit comments

Comments
 (0)