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
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (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, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 //=============================================================================
24 //
25 // Containers script API.
26 //
27 //=============================================================================
28
29 #include "ags/shared/ac/common.h" // quit
30 #include "ags/engine/ac/string.h"
31 #include "ags/engine/ac/dynobj/cc_dynamic_array.h"
32 #include "ags/engine/ac/dynobj/cc_dynamic_object.h"
33 #include "ags/engine/ac/dynobj/script_dict.h"
34 #include "ags/engine/ac/dynobj/script_set.h"
35 #include "ags/engine/ac/dynobj/script_string.h"
36 #include "ags/engine/script/script_api.h"
37 #include "ags/engine/script/script_runtime.h"
38 #include "ags/shared/util/bbop.h"
39 #include "ags/globals.h"
40
41 namespace AGS3 {
42
43 //=============================================================================
44 //
45 // Dictionary of strings script API.
46 //
47 //=============================================================================
48
Dict_CreateImpl(bool sorted,bool case_sensitive)49 ScriptDictBase *Dict_CreateImpl(bool sorted, bool case_sensitive) {
50 ScriptDictBase *dic;
51 if (sorted) {
52 if (case_sensitive)
53 dic = new ScriptDict();
54 else
55 dic = new ScriptDictCI();
56 } else {
57 if (case_sensitive)
58 dic = new ScriptHashDict();
59 else
60 dic = new ScriptHashDictCI();
61 }
62 return dic;
63 }
64
Dict_Create(bool sorted,bool case_sensitive)65 ScriptDictBase *Dict_Create(bool sorted, bool case_sensitive) {
66 ScriptDictBase *dic = Dict_CreateImpl(sorted, case_sensitive);
67 ccRegisterManagedObject(dic, dic);
68 return dic;
69 }
70
71 // TODO: we need memory streams
Dict_Unserialize(int index,const char * serializedData,int dataSize)72 ScriptDictBase *Dict_Unserialize(int index, const char *serializedData, int dataSize) {
73 if (dataSize < (int)sizeof(int32_t) * 2)
74 quit("Dict_Unserialize: not enough data.");
75 const char *ptr = serializedData;
76 const int sorted = BBOp::Int32FromLE(*((const int *)ptr));
77 ptr += sizeof(int32_t);
78 const int cs = BBOp::Int32FromLE(*((const int *)ptr));
79 ptr += sizeof(int32_t);
80 ScriptDictBase *dic = Dict_CreateImpl(sorted != 0, cs != 0);
81 dic->Unserialize(index, ptr, dataSize -= sizeof(int32_t) * 2);
82 return dic;
83 }
84
Dict_Clear(ScriptDictBase * dic)85 void Dict_Clear(ScriptDictBase *dic) {
86 dic->Clear();
87 }
88
Dict_Contains(ScriptDictBase * dic,const char * key)89 bool Dict_Contains(ScriptDictBase *dic, const char *key) {
90 return dic->Contains(key);
91 }
92
Dict_Get(ScriptDictBase * dic,const char * key)93 const char *Dict_Get(ScriptDictBase *dic, const char *key) {
94 auto *str = dic->Get(key);
95 return str ? CreateNewScriptString(str) : nullptr;
96 }
97
Dict_Remove(ScriptDictBase * dic,const char * key)98 bool Dict_Remove(ScriptDictBase *dic, const char *key) {
99 return dic->Remove(key);
100 }
101
Dict_Set(ScriptDictBase * dic,const char * key,const char * value)102 bool Dict_Set(ScriptDictBase *dic, const char *key, const char *value) {
103 return dic->Set(key, value);
104 }
105
Dict_GetCompareStyle(ScriptDictBase * dic)106 int Dict_GetCompareStyle(ScriptDictBase *dic) {
107 return dic->IsCaseSensitive() ? 1 : 0;
108 }
109
Dict_GetSortStyle(ScriptDictBase * dic)110 int Dict_GetSortStyle(ScriptDictBase *dic) {
111 return dic->IsSorted() ? 1 : 0;
112 }
113
Dict_GetItemCount(ScriptDictBase * dic)114 int Dict_GetItemCount(ScriptDictBase *dic) {
115 return dic->GetItemCount();
116 }
117
Dict_GetKeysAsArray(ScriptDictBase * dic)118 void *Dict_GetKeysAsArray(ScriptDictBase *dic) {
119 std::vector<const char *> items;
120 dic->GetKeys(items);
121 if (items.size() == 0)
122 return nullptr;
123 DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items);
124 return arr.second;
125 }
126
Dict_GetValuesAsArray(ScriptDictBase * dic)127 void *Dict_GetValuesAsArray(ScriptDictBase *dic) {
128 std::vector<const char *> items;
129 dic->GetValues(items);
130 if (items.size() == 0)
131 return nullptr;
132 DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items);
133 return arr.second;
134 }
135
Sc_Dict_Create(const RuntimeScriptValue * params,int32_t param_count)136 RuntimeScriptValue Sc_Dict_Create(const RuntimeScriptValue *params, int32_t param_count) {
137 API_SCALL_OBJAUTO_PBOOL2(ScriptDictBase, Dict_Create);
138 }
139
Sc_Dict_Clear(void * self,const RuntimeScriptValue * params,int32_t param_count)140 RuntimeScriptValue Sc_Dict_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) {
141 API_OBJCALL_VOID(ScriptDictBase, Dict_Clear);
142 }
143
Sc_Dict_Contains(void * self,const RuntimeScriptValue * params,int32_t param_count)144 RuntimeScriptValue Sc_Dict_Contains(void *self, const RuntimeScriptValue *params, int32_t param_count) {
145 API_OBJCALL_BOOL_POBJ(ScriptDictBase, Dict_Contains, const char);
146 }
147
Sc_Dict_Get(void * self,const RuntimeScriptValue * params,int32_t param_count)148 RuntimeScriptValue Sc_Dict_Get(void *self, const RuntimeScriptValue *params, int32_t param_count) {
149 API_CONST_OBJCALL_OBJ_POBJ(ScriptDictBase, const char, _GP(myScriptStringImpl), Dict_Get, const char);
150 }
151
Sc_Dict_Remove(void * self,const RuntimeScriptValue * params,int32_t param_count)152 RuntimeScriptValue Sc_Dict_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) {
153 API_OBJCALL_BOOL_POBJ(ScriptDictBase, Dict_Remove, const char);
154 }
155
Sc_Dict_Set(void * self,const RuntimeScriptValue * params,int32_t param_count)156 RuntimeScriptValue Sc_Dict_Set(void *self, const RuntimeScriptValue *params, int32_t param_count) {
157 API_OBJCALL_BOOL_POBJ2(ScriptDictBase, Dict_Set, const char, const char);
158 }
159
Sc_Dict_GetCompareStyle(void * self,const RuntimeScriptValue * params,int32_t param_count)160 RuntimeScriptValue Sc_Dict_GetCompareStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
161 API_OBJCALL_INT(ScriptDictBase, Dict_GetCompareStyle);
162 }
163
Sc_Dict_GetSortStyle(void * self,const RuntimeScriptValue * params,int32_t param_count)164 RuntimeScriptValue Sc_Dict_GetSortStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
165 API_OBJCALL_INT(ScriptDictBase, Dict_GetSortStyle);
166 }
167
Sc_Dict_GetItemCount(void * self,const RuntimeScriptValue * params,int32_t param_count)168 RuntimeScriptValue Sc_Dict_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) {
169 API_OBJCALL_INT(ScriptDictBase, Dict_GetItemCount);
170 }
171
Sc_Dict_GetKeysAsArray(void * self,const RuntimeScriptValue * params,int32_t param_count)172 RuntimeScriptValue Sc_Dict_GetKeysAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) {
173 API_OBJCALL_OBJ(ScriptDictBase, void, _GP(globalDynamicArray), Dict_GetKeysAsArray);
174 }
175
Sc_Dict_GetValuesAsArray(void * self,const RuntimeScriptValue * params,int32_t param_count)176 RuntimeScriptValue Sc_Dict_GetValuesAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) {
177 API_OBJCALL_OBJ(ScriptDictBase, void, _GP(globalDynamicArray), Dict_GetValuesAsArray);
178 }
179
180 //=============================================================================
181 //
182 // Set of strings script API.
183 //
184 //=============================================================================
185
Set_CreateImpl(bool sorted,bool case_sensitive)186 ScriptSetBase *Set_CreateImpl(bool sorted, bool case_sensitive) {
187 ScriptSetBase *set;
188 if (sorted) {
189 if (case_sensitive)
190 set = new ScriptSet();
191 else
192 set = new ScriptSetCI();
193 } else {
194 if (case_sensitive)
195 set = new ScriptHashSet();
196 else
197 set = new ScriptHashSetCI();
198 }
199 return set;
200 }
201
Set_Create(bool sorted,bool case_sensitive)202 ScriptSetBase *Set_Create(bool sorted, bool case_sensitive) {
203 ScriptSetBase *set = Set_CreateImpl(sorted, case_sensitive);
204 ccRegisterManagedObject(set, set);
205 return set;
206 }
207
208 // TODO: we need memory streams
Set_Unserialize(int index,const char * serializedData,int dataSize)209 ScriptSetBase *Set_Unserialize(int index, const char *serializedData, int dataSize) {
210 if (dataSize < (int)sizeof(int32_t) * 2)
211 quit("Set_Unserialize: not enough data.");
212 const char *ptr = serializedData;
213 const int sorted = BBOp::Int32FromLE(*((const int *)ptr));
214 ptr += sizeof(int32_t);
215 const int cs = BBOp::Int32FromLE(*((const int *)ptr));
216 ptr += sizeof(int32_t);
217 ScriptSetBase *set = Set_CreateImpl(sorted != 0, cs != 0);
218 set->Unserialize(index, ptr, dataSize -= sizeof(int32_t) * 2);
219 return set;
220 }
221
Set_Add(ScriptSetBase * set,const char * item)222 bool Set_Add(ScriptSetBase *set, const char *item) {
223 return set->Add(item);
224 }
225
Set_Clear(ScriptSetBase * set)226 void Set_Clear(ScriptSetBase *set) {
227 set->Clear();
228 }
229
Set_Contains(ScriptSetBase * set,const char * item)230 bool Set_Contains(ScriptSetBase *set, const char *item) {
231 return set->Contains(item);
232 }
233
Set_Remove(ScriptSetBase * set,const char * item)234 bool Set_Remove(ScriptSetBase *set, const char *item) {
235 return set->Remove(item);
236 }
237
Set_GetCompareStyle(ScriptSetBase * set)238 int Set_GetCompareStyle(ScriptSetBase *set) {
239 return set->IsCaseSensitive() ? 1 : 0;
240 }
241
Set_GetSortStyle(ScriptSetBase * set)242 int Set_GetSortStyle(ScriptSetBase *set) {
243 return set->IsSorted() ? 1 : 0;
244 }
245
Set_GetItemCount(ScriptSetBase * set)246 int Set_GetItemCount(ScriptSetBase *set) {
247 return set->GetItemCount();
248 }
249
Set_GetItemsAsArray(ScriptSetBase * set)250 void *Set_GetItemsAsArray(ScriptSetBase *set) {
251 std::vector<const char *> items;
252 set->GetItems(items);
253 if (items.size() == 0)
254 return nullptr;
255 DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items);
256 return arr.second;
257 }
258
Sc_Set_Create(const RuntimeScriptValue * params,int32_t param_count)259 RuntimeScriptValue Sc_Set_Create(const RuntimeScriptValue *params, int32_t param_count) {
260 API_SCALL_OBJAUTO_PBOOL2(ScriptSetBase, Set_Create);
261 }
262
Sc_Set_Add(void * self,const RuntimeScriptValue * params,int32_t param_count)263 RuntimeScriptValue Sc_Set_Add(void *self, const RuntimeScriptValue *params, int32_t param_count) {
264 API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Add, const char);
265 }
266
Sc_Set_Clear(void * self,const RuntimeScriptValue * params,int32_t param_count)267 RuntimeScriptValue Sc_Set_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) {
268 API_OBJCALL_VOID(ScriptSetBase, Set_Clear);
269 }
270
Sc_Set_Contains(void * self,const RuntimeScriptValue * params,int32_t param_count)271 RuntimeScriptValue Sc_Set_Contains(void *self, const RuntimeScriptValue *params, int32_t param_count) {
272 API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Contains, const char);
273 }
274
Sc_Set_Remove(void * self,const RuntimeScriptValue * params,int32_t param_count)275 RuntimeScriptValue Sc_Set_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) {
276 API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Remove, const char);
277 }
278
Sc_Set_GetCompareStyle(void * self,const RuntimeScriptValue * params,int32_t param_count)279 RuntimeScriptValue Sc_Set_GetCompareStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
280 API_OBJCALL_INT(ScriptSetBase, Set_GetCompareStyle);
281 }
282
Sc_Set_GetSortStyle(void * self,const RuntimeScriptValue * params,int32_t param_count)283 RuntimeScriptValue Sc_Set_GetSortStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
284 API_OBJCALL_INT(ScriptSetBase, Set_GetSortStyle);
285 }
286
Sc_Set_GetItemCount(void * self,const RuntimeScriptValue * params,int32_t param_count)287 RuntimeScriptValue Sc_Set_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) {
288 API_OBJCALL_INT(ScriptSetBase, Set_GetItemCount);
289 }
290
Sc_Set_GetItemAsArray(void * self,const RuntimeScriptValue * params,int32_t param_count)291 RuntimeScriptValue Sc_Set_GetItemAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) {
292 API_OBJCALL_OBJ(ScriptSetBase, void, _GP(globalDynamicArray), Set_GetItemsAsArray);
293 }
294
295
296
RegisterContainerAPI()297 void RegisterContainerAPI() {
298 ccAddExternalStaticFunction("Dictionary::Create", Sc_Dict_Create);
299 ccAddExternalObjectFunction("Dictionary::Clear", Sc_Dict_Clear);
300 ccAddExternalObjectFunction("Dictionary::Contains", Sc_Dict_Contains);
301 ccAddExternalObjectFunction("Dictionary::Get", Sc_Dict_Get);
302 ccAddExternalObjectFunction("Dictionary::Remove", Sc_Dict_Remove);
303 ccAddExternalObjectFunction("Dictionary::Set", Sc_Dict_Set);
304 ccAddExternalObjectFunction("Dictionary::get_CompareStyle", Sc_Dict_GetCompareStyle);
305 ccAddExternalObjectFunction("Dictionary::get_SortStyle", Sc_Dict_GetSortStyle);
306 ccAddExternalObjectFunction("Dictionary::get_ItemCount", Sc_Dict_GetItemCount);
307 ccAddExternalObjectFunction("Dictionary::GetKeysAsArray", Sc_Dict_GetKeysAsArray);
308 ccAddExternalObjectFunction("Dictionary::GetValuesAsArray", Sc_Dict_GetValuesAsArray);
309
310 ccAddExternalStaticFunction("Set::Create", Sc_Set_Create);
311 ccAddExternalObjectFunction("Set::Add", Sc_Set_Add);
312 ccAddExternalObjectFunction("Set::Clear", Sc_Set_Clear);
313 ccAddExternalObjectFunction("Set::Contains", Sc_Set_Contains);
314 ccAddExternalObjectFunction("Set::Remove", Sc_Set_Remove);
315 ccAddExternalObjectFunction("Set::get_CompareStyle", Sc_Set_GetCompareStyle);
316 ccAddExternalObjectFunction("Set::get_SortStyle", Sc_Set_GetSortStyle);
317 ccAddExternalObjectFunction("Set::get_ItemCount", Sc_Set_GetItemCount);
318 ccAddExternalObjectFunction("Set::GetItemsAsArray", Sc_Set_GetItemAsArray);
319 }
320
321 } // namespace AGS3
322