Code optimization for array expression

This commit is contained in:
NovaRain
2020-10-11 10:13:52 +08:00
parent fa9aa6dc6f
commit 9a3b770182
3 changed files with 39 additions and 33 deletions
+29 -29
View File
@@ -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;
}
+9 -3
View File
@@ -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);
+1 -1
View File
@@ -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 {