Expanded create/temp_array functions to allow creating a new "lookup" type of associative array (from Mr.Stalin)

This commit is contained in:
NovaRain
2019-01-08 06:52:00 +08:00
parent 4f48926105
commit e320acce0b
7 changed files with 81 additions and 52 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
;Controls the elevators
;Image must match up with the image of an existing elevator (can be overrided in sfall 3.8.14 or newer)
;Image must match up with the image of an existing elevator (can be overrided in sfall 4.1.4/3.8.14 or newer)
;Make sure you specify the correct number of exit targets
;The maximum number of elevators is currently capped at 50
;Use the line number (0-indexed) of the corresponding FRM in intrface.lst to set the appearance of the elevator
+7 -5
View File
@@ -151,14 +151,16 @@ Example:
*mixed means any type
> int create_array(int size, int nothing):
> int create_array(int size, int flags):
- creates permanent array (but not "saved")
- if size is >= 0, creates list with given size
- if size == -1, creates map (associative array)
- second argument is not used yet, just use 0
- if size == -1 and flags == 2, creates a "lookup" map in which the values of existing keys are read-only and can't be updated.
This type of array allows you to store a zero (0) key value
- NOTE: in earlier versions (up to 4.1.3/3.8.13) the second argument is not used, just use 0
- returns arrayID (valid until array is deleted)
> int temp_array(int size, int nothing):
> int temp_array(int size, int flags):
- works exactly like "create_array", only created array becomes "temporary"
> void fix_array(int arrayID):
@@ -169,7 +171,7 @@ Example:
- if used on list, "key" must be numeric and within valid index range (0..size-1)
- if used on map, key can be of any type
- to "unset" a value from map, just set it to zero (0)
- NOTE: to add a value of 0 for the key, use the float value (0.0)
- NOTE: to add a value of 0 for the key, use the float value of 0.0
- this works exactly like statement:
arrayID[key] := value;
@@ -183,7 +185,7 @@ Example:
- changes array size
- applicable to maps too, but only to reduce elements
- there are number of special negative values of "size" which perform various operations on the array,
use macros sort_array, sort_array_reverse, reverse_array, shuffle_array from sfall.h header
use macros sort_array, sort_array_reverse, reverse_array, shuffle_array from sfall.h header
> void free_array(int arrayID):
- deletes any array
+11
View File
@@ -20,6 +20,9 @@
/*
Generic array functions
*/
// returns True if the specified key exists in the associative array
procedure map_contains_key(variable arrayMap, variable key);
// push new item at the end of array, returns array
procedure array_push(variable array, variable item);
@@ -151,6 +154,14 @@ procedure load_collection(variable name);
#define ARRAY_SET_BLOCK_SIZE (10)
procedure map_contains_key(variable arrayMap, variable key) begin
variable i;
for (i := 0; i < len_array(arrayMap); i++) begin
if (array_key(arrayMap, i) == key) then return true;
end
return false;
end
/**
* Returns first index of zero value
*/
+4
View File
@@ -102,6 +102,10 @@
#define create_array_map (create_array(-1, 0))
// create temporary map
#define temp_array_map (temp_array(-1, 0))
// create persistent lookup map (see arrays.txt for details)
#define create_lookup_map (create_array(-1, 2))
// create temporary lookup map
#define temp_lookup_map (temp_array(-1, 2))
// true if array is map, false otherwise
#define array_is_map(x) (array_key(x, -1) == 1)
// returns temp list with names of all arrays saved with save_array() in alphabetical order
+2 -2
View File
@@ -132,13 +132,13 @@
0x819d - void set_sfall_global(string/int varname, int/float value)
0x819e - int get_sfall_global_int(string/int varname)
0x819f - float get_sfall_global_float(string/int varname)
0x822d - int create_array(int elementcount, int elementsize)
0x822d - int create_array(int elementcount, int flags)
0x822e - void set_array(int array, any element, any value)
0x822f - any get_array(int array, any element)
0x8230 - void free_array(int array)
0x8231 - int len_array(int array)
0x8232 - void resize_array(int array, int newelementcount)
0x8233 - int temp_array(int elementcount, int elementsize)
0x8233 - int temp_array(int elementcount, int flags)
0x8234 - void fix_array(int array)
0x8239 - int scan_array(int array, int/float var)
0x8256 - int array_key(int array, int index)
+31 -20
View File
@@ -312,7 +312,6 @@ void DESetArray(int id, const DWORD* types, const void* data) {
//memcpy(arrays[id].data, data, arrays[id].len*arrays[id].datalen);
}
/*
Array manipulation functions for script operators
TODO: move somewhere else
@@ -359,10 +358,14 @@ DWORD _stdcall getScriptTypeBySfallType(DWORD dataType) {
}
}
DWORD _stdcall CreateArray(int len, DWORD nothing) {
DWORD _stdcall CreateArray(int len, DWORD flags) {
sArrayVar var;
if (len < 0) var.flags |= ARRAYFLAG_ASSOC;
else if (len > ARRAY_MAX_SIZE) len = ARRAY_MAX_SIZE; // safecheck
var.flags = (flags & 0xFFFFFFFE); // reset 1 bit
if (len < 0) {
var.flags |= ARRAYFLAG_ASSOC;
} else if (len > ARRAY_MAX_SIZE) {
len = ARRAY_MAX_SIZE; // safecheck
}
if (!var.isAssoc()) {
var.val.resize(len);
}
@@ -377,8 +380,8 @@ DWORD _stdcall CreateArray(int len, DWORD nothing) {
return nextarrayid++;
}
DWORD _stdcall TempArray(DWORD len, DWORD nothing) {
DWORD id = CreateArray(len, nothing);
DWORD _stdcall TempArray(DWORD len, DWORD flags) {
DWORD id = CreateArray(len, flags);
tempArrays.insert(id);
return id;
}
@@ -421,7 +424,7 @@ DWORD _stdcall GetArrayKey(DWORD id, int index, DWORD* resultType) {
DWORD _stdcall GetArray(DWORD id, DWORD key, DWORD keyType, DWORD* resultType) {
*resultType = VAR_TYPE_INT;
if(arrays.find(id)==arrays.end()) return 0;
if (arrays.find(id) == arrays.end()) return 0;
int el;
sArrayVar &arr = arrays[id];
if (arr.isAssoc()) {
@@ -448,17 +451,24 @@ DWORD _stdcall GetArray(DWORD id, DWORD key, DWORD keyType, DWORD* resultType) {
}
return 0;
}
void _stdcall SetArray(DWORD id, DWORD key, DWORD keyType, DWORD val, DWORD valType, DWORD allowUnset) {
keyType = getSfallTypeByScriptType(keyType);
valType = getSfallTypeByScriptType(valType);
if(arrays.find(id)==arrays.end()) return;
if (arrays.find(id) == arrays.end()) return;
int el;
sArrayVar &arr = arrays[id];
if (arrays[id].isAssoc()) {
sArrayElement sEl(key, keyType);
ArrayKeysMap::iterator elIter = arr.keyHash.find(sEl);
el = (elIter != arr.keyHash.end()) ? elIter->second : -1;
if (valType == DATATYPE_INT && val == 0 && allowUnset) {
el = (elIter != arr.keyHash.end())
? elIter->second
: -1;
bool lookupMap = (arr.flags & ARRAYFLAG_CONSTVAL) != 0;
if (lookupMap && el != -1) return; // don't update value of key
if (allowUnset && !lookupMap && (valType == DATATYPE_INT && val == 0)) {
// after assigning zero to a key, no need to store it, because "get_array" returns 0 for non-existent keys: try unset
if (el >= 0) {
// remove from hashtable
@@ -603,15 +613,15 @@ int _stdcall ScanArray(DWORD id, DWORD val, DWORD datatype, DWORD* resultType) {
for (DWORD i = 0; i < arrays[id].val.size(); i += step) {
sArrayElement &el = arrays[id].val[i + step - 1];
if (el.type == datatype) {
if ((datatype != DATATYPE_STR && *(DWORD*)&(el.intVal) == val) ||
(datatype == DATATYPE_STR && strcmp(el.strVal, (char*)val) == 0)) {
if (arrays[id].isAssoc()) { // return key instead of index for associative arrays
*resultType = getScriptTypeBySfallType(arrays[id].val[i].type);
return *(DWORD *)&arrays[id].val[i].intVal;
} else {
return i;
}
}
if ((datatype != DATATYPE_STR && *(DWORD*)&(el.intVal) == val) ||
(datatype == DATATYPE_STR && strcmp(el.strVal, (char*)val) == 0)) {
if (arrays[id].isAssoc()) { // return key instead of index for associative arrays
*resultType = getScriptTypeBySfallType(arrays[id].val[i].type);
return *(DWORD *)&arrays[id].val[i].intVal;
} else {
return i;
}
}
}
}
return -1;
@@ -635,8 +645,9 @@ DWORD _stdcall LoadArray(DWORD key, DWORD keyType) {
}
} else {
ArrayKeysMap::iterator it = savedArrays.find(keyEl);
if (it != savedArrays.end())
if (it != savedArrays.end()) {
return it->second;
}
}
}
return 0; // not found
+3 -2
View File
@@ -74,6 +74,7 @@ struct sArrayVarOld
};
#define ARRAYFLAG_ASSOC (1) // is map
#define ARRAYFLAG_CONSTVAL (2) // don't update value of key if the key exists in map
typedef std::tr1::unordered_map<sArrayElement, DWORD, sArrayElement_HashFunc, sArrayElement_EqualFunc> ArrayKeysMap;
@@ -148,9 +149,9 @@ const char* _stdcall GetSfallTypeName(DWORD dataType);
DWORD _stdcall getSfallTypeByScriptType(DWORD varType);
DWORD _stdcall getScriptTypeBySfallType(DWORD dataType);
// creates new normal (persistent) array. len == -1 specifies associative array (map)
DWORD _stdcall CreateArray(int len, DWORD nothing);
DWORD _stdcall CreateArray(int len, DWORD flags);
// same as CreateArray, but creates temporary array instead (will die at the end of the frame)
DWORD _stdcall TempArray(DWORD len, DWORD nothing);
DWORD _stdcall TempArray(DWORD len, DWORD flags);
// destroys array
void _stdcall FreeArray(DWORD id);
/*