ScummVM API documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 
33 namespace Twp {
34 
35 HSQOBJECT sqrootTbl(HSQUIRRELVM v);
36 
37 template<typename T>
38 HSQOBJECT sqtoobj(HSQUIRRELVM v, T value);
39 
40 template<typename T>
41 SQRESULT sqget(HSQUIRRELVM v, int index, T &value);
42 
43 SQInteger sqpush(HSQUIRRELVM v);
44 
45 template<typename T>
46 SQInteger sqpush(HSQUIRRELVM v, T value);
47 
48 template<typename T, typename... Args>
49 void sqpush(HSQUIRRELVM v, T first, Args... args) {
50  sqpush(v, first);
51  sqpush(v, Common::move(args)...);
52 }
53 
54 // set field
55 template<typename T>
56 void 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 
66 template<typename T>
67 SQRESULT 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 
82 template<typename T>
83 SQRESULT sqgetf(HSQOBJECT o, const Common::String &name, T &value) {
84  HSQUIRRELVM v = g_twp->getVm();
85  return sqgetf(v, o, name, value);
86 }
87 
88 template<typename T>
89 SQRESULT sqgetf(const Common::String &name, T &value) {
90  HSQUIRRELVM v = g_twp->getVm();
91  return sqgetf(v, sqrootTbl(v), name, value);
92 }
93 
94 void setId(HSQOBJECT &o, int id);
95 
96 void sqgetarray(HSQUIRRELVM v, HSQOBJECT o, Common::Array<Common::String> &arr);
97 SQRESULT sqgetarray(HSQUIRRELVM v, int i, Common::Array<Common::String> &arr);
98 SQRESULT sqgetarray(HSQUIRRELVM v, int i, Common::Array<Common::SharedPtr<SoundDefinition> > &arr);
99 
100 template<typename TFunc>
101 void 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 
115 SQRESULT sqgetpairs(HSQOBJECT obj, void func(const Common::String &key, HSQOBJECT &obj, void *data), void *data);
116 
117 template<typename TFunc>
118 SQRESULT 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 
136 template<typename T>
137 void 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 
147 bool sqrawexists(HSQOBJECT obj, const Common::String &name);
148 void sqsetdelegate(HSQOBJECT obj, HSQOBJECT del);
149 
150 void sqpushfunc(HSQUIRRELVM v, HSQOBJECT o, const char *name);
151 int sqparamCount(HSQUIRRELVM v, HSQOBJECT obj, const Common::String &name);
152 void sqcall(const char *name, const Common::Array<HSQOBJECT> &args);
153 
154 template<typename... T>
155 void sqcall(const char *name, T... args);
156 
157 template<typename... T>
158 void sqcall(HSQOBJECT o, const char *name, T... args);
159 
160 template<typename TResult, typename... T>
161 static void sqcallfunc(TResult &result, HSQOBJECT o, const char *name, T... args);
162 
163 template<typename TResult, typename... T>
164 static void sqcallfunc(TResult &result, const char *name, T... args);
165 
166 void sqexec(HSQUIRRELVM v, const char *code, const char *filename = nullptr);
167 
168 class Room;
169 class Object;
170 
171 int getId(HSQOBJECT table);
172 Common::SharedPtr<Room> sqroom(HSQOBJECT table);
173 Common::SharedPtr<Room> sqroom(HSQUIRRELVM v, int i);
174 Common::SharedPtr<Room> getRoom(int id);
176 Common::SharedPtr<Object> sqobj(HSQUIRRELVM v, int i);
177 Common::SharedPtr<Object> sqobj(int i);
178 Common::SharedPtr<Object> sqactor(HSQOBJECT table);
179 Common::SharedPtr<Object> sqactor(HSQUIRRELVM v, int i);
181 Common::SharedPtr<SoundDefinition> sqsounddef(int id);
183 Common::SharedPtr<ThreadBase> sqthread(HSQUIRRELVM v, int id);
184 Common::SharedPtr<ThreadBase> sqthread(int id);
185 Light *sqlight(int id);
186 Light *sqlight(HSQUIRRELVM v, int i);
187 
188 template<typename... T>
189 void 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 
202 template<typename... T>
203 void 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 
217 template<typename... T>
218 void 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 
233 template<typename TResult, typename... T>
234 void 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 
260 template<typename TResult, typename... T>
261 void 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: sqvm.h:33
Definition: str.h:59
Definition: squirrel.h:153
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: ptr.h:159
Definition: achievements_tables.h:27