Script.h
1 /*
2  * Copyright (C) 2020-2026 by Marc Boris Duerner
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27  * MA 02110-1301 USA
28  */
29 
30 #ifndef PT_LUA_SCRIPT_H
31 #define PT_LUA_SCRIPT_H
32 
33 #include <Pt/Lua/Api.h>
34 #include <Pt/System/Selectable.h>
35 #include <Pt/Signal.h>
36 
37 struct lua_State;
38 struct lua_Debug;
39 
40 #include <string>
41 
42 #if __cplusplus >= 202002L
43 #include <Pt/Slot.h>
44 #include <Pt/Coroutine.h>
45 #endif
46 
47 namespace Pt {
48 
49 class Any;
50 
51 namespace Reflex { class Type; }
52 
53 namespace Lua {
54 
55 class AsyncCall;
56 class Context;
57 class Call;
58 
59 #if __cplusplus >= 202002L
60 class AsyncAdvance;
61 #endif
62 
67 class PT_LUA_API Script : public System::Selectable
68  , public Connectable
69 {
70  public:
71  enum Status
72  {
73  Yield,
74  NativeCall,
75  ScriptOk,
76  ScriptError
77  };
78 
79  Script(Context& ctx, const char* script);
80 
81  ~Script();
82 
83  void beginAdvance();
84 
85  Status endAdvance() const;
86 
87  Pt::Signal<>& advanced();
88 
89  Status advance();
90 
91  const std::string& errorMessage() const
92  { return _errorMsg; }
93 
94  static Script* fromState(lua_State* L);
95 
96 #if __cplusplus >= 202002L
97 
103 #endif
104 
105  protected:
106  bool onRun();
107 
109 
111 
112  void onCancel();
113 
114  private:
115  Script(const Script&);
116  Script& operator=(const Script&);
117 
118 #if __cplusplus >= 202002L
119  friend class AsyncAdvance;
120 
121  void attachAwaiter(AsyncAdvance& awaiter);
122 
123  void detachAwaiter(AsyncAdvance& awaiter);
124 #endif
125 
126  bool onCall();
127 
128  void onAsyncCall();
129 
130  void onAsyncCallFinished();
131 
132  bool onAsyncCallReady();
133 
134  int pushResult(Pt::Any& value, Pt::Reflex::Type& type);
135 
136  void resume();
137 
138  bool isCancelled() const;
139 
140  void setError(const std::string& msg);
141 
142  static void yieldHook(lua_State* L, lua_Debug* ar);
143 
144  private:
145  Context& _ctx;
146  lua_State* _co;
147  bool _isCancelled;
148  Status _lastStatus;
149  std::string _errorMsg;
150  Pt::Signal<> _advanced;
151 
152  Call* _pendingCall;
153  AsyncCall* _pendingAsyncCall;
154  AsyncCall* _activeAsyncCall;
155 
156  #if __cplusplus >= 202002L
157  AsyncAdvance* _awaiter = nullptr;
158  #endif
159 };
160 
161 #if __cplusplus >= 202002L
162 
170 class PT_LUA_API AsyncAdvance : public Pt::Awaiter
171  , public Pt::Connectable
172 {
173  public:
174  AsyncAdvance(Script& script);
175 
176  ~AsyncAdvance();
177 
178  Script::Status await_resume();
179 
180  private:
181  friend class Script;
182 
183  void onBegin() override;
184 
185  void onCancel() override;
186 
187  void onDetach();
188 
189  void onAdvanced();
190 
191  Script& script();
192 
193  Script* _script;
194  bool _isPending;
195 };
196 
197 #endif // __cplusplus >= 202002L
198 
199 } // namespace
200 
201 } // namespace
202 
203 #endif // include guard
Core module.
Definition: Allocator.h:33
Multicast Signal to call multiple slots.
Definition: Signal.h:190
Scripting context.
Definition: Context.h:51
AsyncAdvance advanceAsync()
Asynchronously advance the Lua script as a C++20 awaitable.
void onCancel()
Blocks until operation has cancelled.
bool onRun()
Check if ready and run.
Awaitable for async advance of a Lua Script.
Definition: Script.h:172
Connection Management for Signal and Slot Objects.
Definition: Connectable.h:50
void onAttach(Pt::System::EventLoop &loop)
Attached to loop.
Dispatches operations through an event loop.
Definition: Selectable.h:45
Thread-safe event loop supporting I/O multiplexing and Timers.
Definition: EventLoop.h:83
Contains an arbitrary type.
Definition: Any.h:64
void onDetach(Pt::System::EventLoop &loop)
Detached from loop.
Lua script.
Definition: Script.h:69
Provides the base class for I/O-driven co_await-able operations.
Definition: Coroutine.h:126