mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Code optimization for array expression
This commit is contained in:
@@ -26,7 +26,7 @@ ArrayKeysMap savedArrays;
|
||||
|
||||
// auto-incremented ID
|
||||
DWORD nextArrayID = 1;
|
||||
// special array ID for array expressions
|
||||
// special array ID for array expressions, contains the ID number of the currently created array
|
||||
DWORD stackArrayId;
|
||||
|
||||
static char get_all_arrays_special_key[] = "...all_arrays...";
|
||||
@@ -318,6 +318,10 @@ int GetNumArrays() {
|
||||
return arrays.size();
|
||||
}
|
||||
|
||||
bool ArrayExist(DWORD id) {
|
||||
return (arrays.find(id) != arrays.end());
|
||||
}
|
||||
|
||||
void GetArrays(int* _arrays) {
|
||||
int pos = 0;
|
||||
array_citr itr = arrays.begin();
|
||||
@@ -381,13 +385,14 @@ void DESetArray(int id, const DWORD* types, const char* data) {
|
||||
*/
|
||||
|
||||
DWORD CreateArray(int len, DWORD flags) {
|
||||
sArrayVar var;
|
||||
var.flags = (flags & 0xFFFFFFFE); // reset 1 bit
|
||||
flags = (flags & ~1); // reset 1 bit
|
||||
if (len < 0) {
|
||||
var.flags |= ARRAYFLAG_ASSOC;
|
||||
flags |= ARRAYFLAG_ASSOC;
|
||||
} else if (len > ARRAY_MAX_SIZE) {
|
||||
len = ARRAY_MAX_SIZE; // safecheck
|
||||
}
|
||||
sArrayVar var(len, flags);
|
||||
|
||||
if (!var.isAssoc()) {
|
||||
var.val.resize(len);
|
||||
}
|
||||
@@ -487,16 +492,12 @@ ScriptValue GetArray(DWORD id, const ScriptValue& key) {
|
||||
return ScriptValue(0);
|
||||
}
|
||||
|
||||
void SetArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool allowUnset) {
|
||||
if (arrays.find(id) == arrays.end()) {
|
||||
return;
|
||||
}
|
||||
int el;
|
||||
void setArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool allowUnset) {
|
||||
sArrayVar &arr = arrays[id];
|
||||
if (arrays[id].isAssoc()) {
|
||||
if (arr.isAssoc()) {
|
||||
sArrayElement sEl(key.rawValue(), key.type());
|
||||
ArrayKeysMap::iterator elIter = arr.keyHash.find(sEl);
|
||||
el = (elIter != arr.keyHash.end())
|
||||
int el = (elIter != arr.keyHash.end())
|
||||
? elIter->second
|
||||
: -1;
|
||||
|
||||
@@ -527,26 +528,26 @@ void SetArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool all
|
||||
arr.val[el].setByType(key.rawValue(), key.type()); // copy data
|
||||
arr.keyHash[arr.val[el]] = el;
|
||||
}
|
||||
arr.val[el+1].setByType(val.rawValue(), val.type());
|
||||
arr.val[el + 1].setByType(val.rawValue(), val.type());
|
||||
}
|
||||
} else {
|
||||
// only update normal array if key is an integer and within array size
|
||||
el = key.asInt();
|
||||
if (key.isInt() && arr.size() > el) {
|
||||
arr.val[el].setByType(val.rawValue(), val.type());
|
||||
} else if (key.isInt()) { // only update normal array if key is an integer and within array size
|
||||
size_t index = key.rawValue();
|
||||
if (arr.val.size() > index) {
|
||||
arr.val[index].setByType(val.rawValue(), val.type());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool allowUnset) {
|
||||
if (!ArrayExist(id)) return;
|
||||
setArray(id, key, val, allowUnset);
|
||||
}
|
||||
|
||||
int LenArray(DWORD id) {
|
||||
array_itr it = arrays.find(id);
|
||||
return (it != arrays.end()) ? it->second.size() : -1;
|
||||
}
|
||||
|
||||
bool ArrayExist(DWORD id) {
|
||||
return (arrays.find(id) != arrays.end());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void ListSort(std::vector<T> &arr, int type) {
|
||||
switch (type) {
|
||||
@@ -738,15 +739,14 @@ void SaveArray(const ScriptValue& key, DWORD id) {
|
||||
Should always return 0!
|
||||
*/
|
||||
long StackArray(const ScriptValue& key, const ScriptValue& val) {
|
||||
DWORD id = stackArrayId;
|
||||
if (id == 0 || arrays.find(id) == arrays.end()) {
|
||||
return 0;
|
||||
if (stackArrayId == 0 || !ArrayExist(stackArrayId)) return 0;
|
||||
|
||||
if (!arrays[stackArrayId].isAssoc()) { // automatically resize array to fit one new element
|
||||
size_t size = arrays[stackArrayId].val.size();
|
||||
if (size >= ARRAY_MAX_SIZE) return 0;
|
||||
if (key.rawValue() >= size) arrays[stackArrayId].val.resize(size + 10); // resize with a small margin
|
||||
}
|
||||
if (!arrays[id].isAssoc()) {
|
||||
// automatically resize array to fit one new element
|
||||
ResizeArray(id, arrays[id].size() + 1);
|
||||
}
|
||||
SetArray(id, key, val, false);
|
||||
setArray(stackArrayId, key, val, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -109,6 +109,10 @@ public:
|
||||
|
||||
sArrayVar() : flags(0), key() {}
|
||||
|
||||
sArrayVar(int len, int flag) : flags(flag), key() {
|
||||
if (len > 0) val.reserve(len + 10);
|
||||
}
|
||||
|
||||
bool isAssoc() const {
|
||||
return (flags & ARRAYFLAG_ASSOC);
|
||||
}
|
||||
@@ -154,6 +158,7 @@ extern ArrayKeysMap savedArrays;
|
||||
long LoadArrays(HANDLE h);
|
||||
void SaveArrays(HANDLE h);
|
||||
int GetNumArrays();
|
||||
bool ArrayExist(DWORD id);
|
||||
void GetArrays(int* arrays);
|
||||
|
||||
void DEGetArray(int id, DWORD* types, char* data);
|
||||
@@ -179,14 +184,15 @@ ScriptValue GetArrayKey(DWORD id, int index);
|
||||
// get array element by index (list) or key (map)
|
||||
ScriptValue GetArray(DWORD id, const ScriptValue& key);
|
||||
|
||||
// set array element by index or key
|
||||
// set array element by index or key (with checking the existence of the array ID)
|
||||
void SetArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool allowUnset);
|
||||
|
||||
// set array element by index or key
|
||||
void setArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool allowUnset);
|
||||
|
||||
// number of elements in list or pairs in map
|
||||
int LenArray(DWORD id);
|
||||
|
||||
bool ArrayExist(DWORD id);
|
||||
|
||||
// change array size (only works with list)
|
||||
long ResizeArray(DWORD id, int newlen);
|
||||
|
||||
|
||||
@@ -890,7 +890,7 @@ void mf_get_ini_section(OpcodeContext& ctx) {
|
||||
*val = '\0';
|
||||
val += 1;
|
||||
|
||||
SetArray(arrayId, ScriptValue(key), ScriptValue(val), false);
|
||||
setArray(arrayId, ScriptValue(key), ScriptValue(val), false);
|
||||
|
||||
key = val + std::strlen(val) + 1;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user