Files
scummvm-cursorfix/engines/ags/engine/ac/script_containers.cpp
2026-02-02 04:50:13 +01:00

319 lines
10 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
//=============================================================================
//
// Containers script API.
//
//=============================================================================
#include "ags/shared/ac/common.h" // quit
#include "ags/engine/ac/string.h"
#include "ags/engine/ac/dynobj/cc_dynamic_array.h"
#include "ags/engine/ac/dynobj/cc_script_object.h"
#include "ags/engine/ac/dynobj/script_dict.h"
#include "ags/engine/ac/dynobj/script_set.h"
#include "ags/engine/ac/dynobj/script_string.h"
#include "ags/engine/ac/dynobj/dynobj_manager.h"
#include "ags/engine/script/script_api.h"
#include "ags/engine/script/script_runtime.h"
#include "ags/shared/util/bbop.h"
#include "ags/globals.h"
namespace AGS3 {
//=============================================================================
//
// Dictionary of strings script API.
//
//=============================================================================
ScriptDictBase *Dict_CreateImpl(bool sorted, bool case_sensitive) {
ScriptDictBase *dic;
if (sorted) {
if (case_sensitive)
dic = new ScriptDict();
else
dic = new ScriptDictCI();
} else {
if (case_sensitive)
dic = new ScriptHashDict();
else
dic = new ScriptHashDictCI();
}
return dic;
}
ScriptDictBase *Dict_Create(bool sorted, bool case_sensitive) {
ScriptDictBase *dic = Dict_CreateImpl(sorted, case_sensitive);
ccRegisterManagedObject(dic, dic);
return dic;
}
// TODO: we need memory streams
ScriptDictBase *Dict_Unserialize(int index, AGS::Shared::Stream *in, size_t data_sz) {
if (data_sz < sizeof(int32_t) * 2)
quit("Dict_Unserialize: not enough data."); // TODO: don't quit, return error
const int sorted = in->ReadInt32();
const int cs = in->ReadInt32();
ScriptDictBase *dic = Dict_CreateImpl(sorted != 0, cs != 0);
dic->Unserialize(index, in, data_sz - sizeof(int32_t) * 2);
return dic;
}
void Dict_Clear(ScriptDictBase *dic) {
dic->Clear();
}
bool Dict_Contains(ScriptDictBase *dic, const char *key) {
return dic->Contains(key);
}
const char *Dict_Get(ScriptDictBase *dic, const char *key) {
auto *str = dic->Get(key);
return str ? CreateNewScriptString(str) : nullptr;
}
bool Dict_Remove(ScriptDictBase *dic, const char *key) {
return dic->Remove(key);
}
bool Dict_Set(ScriptDictBase *dic, const char *key, const char *value) {
return dic->Set(key, value);
}
int Dict_GetCompareStyle(ScriptDictBase *dic) {
return dic->IsCaseSensitive() ? 1 : 0;
}
int Dict_GetSortStyle(ScriptDictBase *dic) {
return dic->IsSorted() ? 1 : 0;
}
int Dict_GetItemCount(ScriptDictBase *dic) {
return dic->GetItemCount();
}
void *Dict_GetKeysAsArray(ScriptDictBase *dic) {
std::vector<const char *> items;
dic->GetKeys(items);
if (items.size() == 0)
return nullptr;
DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items);
return arr.Obj;
}
void *Dict_GetValuesAsArray(ScriptDictBase *dic) {
std::vector<const char *> items;
dic->GetValues(items);
if (items.size() == 0)
return nullptr;
DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items);
return arr.Obj;
}
RuntimeScriptValue Sc_Dict_Create(const RuntimeScriptValue *params, int32_t param_count) {
API_SCALL_OBJAUTO_PBOOL2(ScriptDictBase, Dict_Create);
}
RuntimeScriptValue Sc_Dict_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_VOID(ScriptDictBase, Dict_Clear);
}
RuntimeScriptValue Sc_Dict_Contains(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_BOOL_POBJ(ScriptDictBase, Dict_Contains, const char);
}
RuntimeScriptValue Sc_Dict_Get(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_OBJ_POBJ(ScriptDictBase, const char, _GP(myScriptStringImpl), Dict_Get, const char);
}
RuntimeScriptValue Sc_Dict_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_BOOL_POBJ(ScriptDictBase, Dict_Remove, const char);
}
RuntimeScriptValue Sc_Dict_Set(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_BOOL_POBJ2(ScriptDictBase, Dict_Set, const char, const char);
}
RuntimeScriptValue Sc_Dict_GetCompareStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_INT(ScriptDictBase, Dict_GetCompareStyle);
}
RuntimeScriptValue Sc_Dict_GetSortStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_INT(ScriptDictBase, Dict_GetSortStyle);
}
RuntimeScriptValue Sc_Dict_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_INT(ScriptDictBase, Dict_GetItemCount);
}
RuntimeScriptValue Sc_Dict_GetKeysAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_OBJ(ScriptDictBase, void, _GP(globalDynamicArray), Dict_GetKeysAsArray);
}
RuntimeScriptValue Sc_Dict_GetValuesAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_OBJ(ScriptDictBase, void, _GP(globalDynamicArray), Dict_GetValuesAsArray);
}
//=============================================================================
//
// Set of strings script API.
//
//=============================================================================
ScriptSetBase *Set_CreateImpl(bool sorted, bool case_sensitive) {
ScriptSetBase *set;
if (sorted) {
if (case_sensitive)
set = new ScriptSet();
else
set = new ScriptSetCI();
} else {
if (case_sensitive)
set = new ScriptHashSet();
else
set = new ScriptHashSetCI();
}
return set;
}
ScriptSetBase *Set_Create(bool sorted, bool case_sensitive) {
ScriptSetBase *set = Set_CreateImpl(sorted, case_sensitive);
ccRegisterManagedObject(set, set);
return set;
}
// TODO: we need memory streams
ScriptSetBase *Set_Unserialize(int index, AGS::Shared::Stream *in, size_t data_sz) {
if (data_sz < sizeof(int32_t) * 2)
quit("Set_Unserialize: not enough data."); // TODO: don't quit, return error
const int sorted = in->ReadInt32();
const int cs = in->ReadInt32();
ScriptSetBase *set = Set_CreateImpl(sorted != 0, cs != 0);
set->Unserialize(index, in, data_sz - sizeof(int32_t) * 2);
return set;
}
bool Set_Add(ScriptSetBase *set, const char *item) {
return set->Add(item);
}
void Set_Clear(ScriptSetBase *set) {
set->Clear();
}
bool Set_Contains(ScriptSetBase *set, const char *item) {
return set->Contains(item);
}
bool Set_Remove(ScriptSetBase *set, const char *item) {
return set->Remove(item);
}
int Set_GetCompareStyle(ScriptSetBase *set) {
return set->IsCaseSensitive() ? 1 : 0;
}
int Set_GetSortStyle(ScriptSetBase *set) {
return set->IsSorted() ? 1 : 0;
}
int Set_GetItemCount(ScriptSetBase *set) {
return set->GetItemCount();
}
void *Set_GetItemsAsArray(ScriptSetBase *set) {
std::vector<const char *> items;
set->GetItems(items);
if (items.size() == 0)
return nullptr;
DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items);
return arr.Obj;
}
RuntimeScriptValue Sc_Set_Create(const RuntimeScriptValue *params, int32_t param_count) {
API_SCALL_OBJAUTO_PBOOL2(ScriptSetBase, Set_Create);
}
RuntimeScriptValue Sc_Set_Add(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Add, const char);
}
RuntimeScriptValue Sc_Set_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_VOID(ScriptSetBase, Set_Clear);
}
RuntimeScriptValue Sc_Set_Contains(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Contains, const char);
}
RuntimeScriptValue Sc_Set_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Remove, const char);
}
RuntimeScriptValue Sc_Set_GetCompareStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_INT(ScriptSetBase, Set_GetCompareStyle);
}
RuntimeScriptValue Sc_Set_GetSortStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_INT(ScriptSetBase, Set_GetSortStyle);
}
RuntimeScriptValue Sc_Set_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_INT(ScriptSetBase, Set_GetItemCount);
}
RuntimeScriptValue Sc_Set_GetItemsAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_OBJ(ScriptSetBase, void, _GP(globalDynamicArray), Set_GetItemsAsArray);
}
void RegisterContainerAPI() {
ScFnRegister container_api[] = {
// Dictionary
{"Dictionary::Create", API_FN_PAIR(Dict_Create)},
{"Dictionary::Clear", API_FN_PAIR(Dict_Clear)},
{"Dictionary::Contains", API_FN_PAIR(Dict_Contains)},
{"Dictionary::Get", API_FN_PAIR(Dict_Get)},
{"Dictionary::Remove", API_FN_PAIR(Dict_Remove)},
{"Dictionary::Set", API_FN_PAIR(Dict_Set)},
{"Dictionary::get_CompareStyle", API_FN_PAIR(Dict_GetCompareStyle)},
{"Dictionary::get_SortStyle", API_FN_PAIR(Dict_GetSortStyle)},
{"Dictionary::get_ItemCount", API_FN_PAIR(Dict_GetItemCount)},
{"Dictionary::GetKeysAsArray", API_FN_PAIR(Dict_GetKeysAsArray)},
{"Dictionary::GetValuesAsArray", API_FN_PAIR(Dict_GetValuesAsArray)},
// Set
{"Set::Create", API_FN_PAIR(Set_Create)},
{"Set::Add", API_FN_PAIR(Set_Add)},
{"Set::Clear", API_FN_PAIR(Set_Clear)},
{"Set::Contains", API_FN_PAIR(Set_Contains)},
{"Set::Remove", API_FN_PAIR(Set_Remove)},
{"Set::get_CompareStyle", API_FN_PAIR(Set_GetCompareStyle)},
{"Set::get_SortStyle", API_FN_PAIR(Set_GetSortStyle)},
{"Set::get_ItemCount", API_FN_PAIR(Set_GetItemCount)},
{"Set::GetItemsAsArray", API_FN_PAIR(Set_GetItemsAsArray)},
};
ccAddExternalFunctions361(container_api);
}
} // namespace AGS3