ScummVM API documentation
squtil.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef TWP_SQUTIL_H
23#define TWP_SQUTIL_H
24
25#include "common/util.h"
26#include "common/str.h"
27#include "common/util.h"
28#include "twp/twp.h"
29#include "twp/audio.h"
30#include "twp/vm.h"
31#include "twp/squirrel/squirrel.h"
32
33namespace Twp {
34
35HSQOBJECT sqrootTbl(HSQUIRRELVM v);
36
37template<typename T>
38HSQOBJECT sqtoobj(HSQUIRRELVM v, T value);
39
40template<typename T>
41SQRESULT sqget(HSQUIRRELVM v, int index, T &value);
42
43SQInteger sqpush(HSQUIRRELVM v);
44
45template<typename T>
46SQInteger sqpush(HSQUIRRELVM v, T value);
47
48template<typename T, typename... Args>
49void sqpush(HSQUIRRELVM v, T first, Args... args) {
50 sqpush(v, first);
51 sqpush(v, Common::move(args)...);
52}
53
54// set field
55template<typename T>
56void sqsetf(HSQOBJECT o, const Common::String &key, T obj) {
57 HSQUIRRELVM v = g_twp->getVm();
58 SQInteger top = sq_gettop(v);
59 sq_pushobject(v, o);
60 sq_pushstring(v, key.c_str(), -1);
61 sqpush(v, Common::move(obj));
62 sq_rawset(v, -3);
63 sq_settop(v, top);
64}
65
66template<typename T>
67SQRESULT sqgetf(HSQUIRRELVM v, HSQOBJECT o, const Common::String &name, T &value) {
68 sq_pushobject(v, o);
69 sq_pushstring(v, name.c_str(), -1);
70 if (SQ_FAILED(sq_get(v, -2))) {
71 sq_pop(v, 1);
72 return sq_throwerror(v, "Failed to get field");
73 }
74
75 if (SQ_FAILED(sqget(v, -1, value)))
76 return sq_throwerror(v, "Failed to get field");
77
78 sq_pop(v, 2);
79 return SQ_OK;
80}
81
82template<typename T>
83SQRESULT sqgetf(HSQOBJECT o, const Common::String &name, T &value) {
84 HSQUIRRELVM v = g_twp->getVm();
85 return sqgetf(v, o, name, value);
86}
87
88template<typename T>
89SQRESULT sqgetf(const Common::String &name, T &value) {
90 HSQUIRRELVM v = g_twp->getVm();
91 return sqgetf(v, sqrootTbl(v), name, value);
92}
93
94void setId(HSQOBJECT &o, int id);
95
96void sqgetarray(HSQUIRRELVM v, HSQOBJECT o, Common::Array<Common::String> &arr);
97SQRESULT sqgetarray(HSQUIRRELVM v, int i, Common::Array<Common::String> &arr);
98SQRESULT sqgetarray(HSQUIRRELVM v, int i, Common::Array<Common::SharedPtr<SoundDefinition> > &arr);
99
100template<typename TFunc>
101void sqgetitems(HSQOBJECT o, TFunc func) {
102 HSQUIRRELVM v = g_twp->getVm();
103 sq_pushobject(v, o);
104 sq_pushnull(v);
105 while (SQ_SUCCEEDED(sq_next(v, -2))) {
106 HSQOBJECT obj;
107 if (SQ_FAILED(sqget(v, -1, obj)))
108 error("Failed to get item");
109 func(obj);
110 sq_pop(v, 2);
111 }
112 sq_pop(v, 2);
113}
114
115SQRESULT sqgetpairs(HSQOBJECT obj, void func(const Common::String &key, HSQOBJECT &obj, void *data), void *data);
116
117template<typename TFunc>
118SQRESULT sqgetpairs(HSQOBJECT obj, TFunc func) {
119 HSQUIRRELVM v = g_twp->getVm();
120 sq_pushobject(v, obj);
121 sq_pushnull(v);
122 while (SQ_SUCCEEDED(sq_next(v, -2))) {
123 Common::String key;
124 HSQOBJECT o;
125 if (SQ_FAILED(sqget(v, -1, o)))
126 return sq_throwerror(v, "failed to get object");
127 if (SQ_FAILED(sqget(v, -2, key)))
128 return sq_throwerror(v, "failed to get key");
129 func(key, o);
130 sq_pop(v, 2);
131 }
132 sq_pop(v, 2);
133 return SQ_OK;
134}
135
136template<typename T>
137void sqnewf(HSQOBJECT o, const Common::String &key, T obj) {
138 HSQUIRRELVM v = g_twp->getVm();
139 SQInteger top = sq_gettop(v);
140 sq_pushobject(v, o);
141 sq_pushstring(v, key.c_str(), -1);
142 sqpush(v, obj);
143 sq_newslot(v, -3, SQFalse);
144 sq_settop(v, top);
145}
146
147bool sqrawexists(HSQOBJECT obj, const Common::String &name);
148void sqsetdelegate(HSQOBJECT obj, HSQOBJECT del);
149
150void sqpushfunc(HSQUIRRELVM v, HSQOBJECT o, const char *name);
151int sqparamCount(HSQUIRRELVM v, HSQOBJECT obj, const Common::String &name);
152void sqcall(const char *name, const Common::Array<HSQOBJECT> &args);
153
154template<typename... T>
155void sqcall(const char *name, T... args);
156
157template<typename... T>
158void sqcall(HSQOBJECT o, const char *name, T... args);
159
160template<typename TResult, typename... T>
161static void sqcallfunc(TResult &result, HSQOBJECT o, const char *name, T... args);
162
163template<typename TResult, typename... T>
164static void sqcallfunc(TResult &result, const char *name, T... args);
165
166void sqexec(HSQUIRRELVM v, const char *code, const char *filename = nullptr);
167
168class Room;
169class Object;
170
171int getId(HSQOBJECT table);
173Common::SharedPtr<Room> sqroom(HSQUIRRELVM v, int i);
174Common::SharedPtr<Room> getRoom(int id);
177Common::SharedPtr<Object> sqobj(int i);
179Common::SharedPtr<Object> sqactor(HSQUIRRELVM v, int i);
181Common::SharedPtr<SoundDefinition> sqsounddef(int id);
184Common::SharedPtr<ThreadBase> sqthread(int id);
185Light *sqlight(int id);
186Light *sqlight(HSQUIRRELVM v, int i);
187
188template<typename... T>
189void sqcall(HSQUIRRELVM v, HSQOBJECT o, const char *name, T... args) {
190 constexpr size_t n = sizeof...(T);
191 SQInteger top = sq_gettop(v);
192 sqpushfunc(v, o, name);
193
194 sq_pushobject(v, o);
195 if (n > 0) {
196 sqpush(v, Common::forward<T>(args)...);
197 }
198 sq_call(v, 1 + n, SQFalse, SQTrue);
199 sq_settop(v, top);
200}
201
202template<typename... T>
203void sqcall(HSQOBJECT o, const char *name, T... args) {
204 constexpr size_t n = sizeof...(T);
205 HSQUIRRELVM v = g_twp->getVm();
206 SQInteger top = sq_gettop(v);
207 sqpushfunc(v, o, name);
208
209 sq_pushobject(v, o);
210 if (n > 0) {
211 sqpush(v, Common::forward<T>(args)...);
212 }
213 sq_call(v, 1 + n, SQFalse, SQTrue);
214 sq_settop(v, top);
215}
216
217template<typename... T>
218void sqcall(const char *name, T... args) {
219 constexpr size_t n = sizeof...(T);
220 HSQUIRRELVM v = g_twp->getVm();
221 HSQOBJECT o = sqrootTbl(v);
222 SQInteger top = sq_gettop(v);
223 sqpushfunc(v, o, name);
224
225 sq_pushobject(v, o);
226 if (n > 0) {
227 sqpush(v, Common::forward<T>(args)...);
228 }
229 sq_call(v, 1 + n, SQFalse, SQTrue);
230 sq_settop(v, top);
231}
232
233template<typename TResult, typename... T>
234void sqcallfunc(TResult &result, HSQOBJECT o, const char *name, T... args) {
235 constexpr size_t n = sizeof...(T);
236 HSQUIRRELVM v = g_twp->getVm();
237 SQInteger top = sq_gettop(v);
238 sqpush(v, o);
239 sq_pushstring(v, _SC(name), -1);
240 if (SQ_FAILED(sq_get(v, -2))) {
241 sq_settop(v, top);
242 error("can't find %s function", name);
243 return;
244 }
245 sq_remove(v, -2);
246
247 sqpush(v, o);
248 sqpush(v, Common::forward<T>(args)...);
249 if (SQ_FAILED(sq_call(v, n + 1, SQTrue, SQTrue))) {
250 // sqstd_printcallstack(v);
251 sq_settop(v, top);
252 error("function %s call failed", name);
253 return;
254 }
255 if (SQ_FAILED(sqget(v, -1, result)))
256 error("function %s call failed to get result", name);
257 sq_settop(v, top);
258}
259
260template<typename TResult, typename... T>
261void sqcallfunc(TResult &result, const char *name, T... args) {
262 constexpr size_t n = sizeof...(T);
263 HSQUIRRELVM v = g_twp->getVm();
264 HSQOBJECT o = sqrootTbl(v);
265 SQInteger top = sq_gettop(v);
266 sqpush(v, o);
267 sq_pushstring(v, _SC(name), -1);
268 if (SQ_FAILED(sq_get(v, -2))) {
269 sq_settop(v, top);
270 error("can't find %s function", name);
271 return;
272 }
273 sq_remove(v, -2);
274
275 sqpush(v, o);
276 sqpush(v, Common::forward<T>(args)...);
277 if (SQ_FAILED(sq_call(v, n + 1, SQTrue, SQTrue))) {
278 // sqstd_printcallstack(v);
279 sq_settop(v, top);
280 error("function %s call failed", name);
281 return;
282 }
283 if (SQ_FAILED(sqget(v, -1, result))) {
284 sq_settop(v, top);
285 error("function %s failed to get result", name);
286 return;
287 }
288 sq_settop(v, top);
289}
290
291} // namespace Twp
292
293#endif
Definition: ptr.h:159
Definition: str.h:59
Out move(In first, In last, Out dst)
Definition: algorithm.h:109
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: sqvm.h:34
Definition: squirrel.h:154