@@ -14,6 +14,8 @@ import 'package:lua_dardo_async/lua.dart';
1414import 'interfaces.dart' as portal;
1515import 'package:web_socket_channel/web_socket_channel.dart' ;
1616
17+ part 'lua.context.dart' ;
18+
1719typedef LuaArgs = ({List positional, Map named});
1820typedef 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