mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
214 lines
6.0 KiB
C++
214 lines
6.0 KiB
C++
#pragma once
|
|
|
|
#include "main.h"
|
|
|
|
#include <functional>
|
|
#include <unordered_map>
|
|
#include <Windows.h>
|
|
|
|
#define ARRAY_MAX_STRING (255) // maximum length of string to be stored as array key or value
|
|
#define ARRAY_MAX_SIZE (100000) // maximum number of array elements,
|
|
// so total maximum memory/disk footprint of one array is: 16 + (ARRAY_MAX_STRING + 8) * ARRAY_MAX_SIZE
|
|
|
|
// special actions for arrays using array_resize operator
|
|
#define ARRAY_ACTION_SORT (-2)
|
|
#define ARRAY_ACTION_RSORT (-3)
|
|
#define ARRAY_ACTION_REVERSE (-4)
|
|
#define ARRAY_ACTION_SHUFFLE (-5)
|
|
|
|
|
|
// TODO: rewrite
|
|
class sArrayElement
|
|
{
|
|
public:
|
|
DWORD type; // DATATYPE_*
|
|
DWORD len; // for strings
|
|
union {
|
|
long intVal;
|
|
float floatVal;
|
|
char* strVal;
|
|
};
|
|
|
|
sArrayElement();
|
|
// this constructor does not copy strings (for performance), use set() for actual array elements
|
|
sArrayElement(DWORD _val, DWORD _dataType);
|
|
sArrayElement(const long&);
|
|
|
|
// free string resource from memory, has to be called manually when deleting element
|
|
void clearData();
|
|
|
|
// set* methods will actually COPY strings, use this when acquiring data from the scripting engine
|
|
void setByType(DWORD val, DWORD dataType);
|
|
|
|
void sArrayElement::set( const sArrayElement &el )
|
|
{
|
|
setByType(el.intVal, el.type);
|
|
}
|
|
|
|
void set(long val);
|
|
void set(float val);
|
|
void set(const char* val, int _len = -1);
|
|
void unset();
|
|
|
|
DWORD sArrayElement::getHash() const
|
|
{
|
|
return getHashStatic(*(DWORD*)&intVal, type);
|
|
}
|
|
|
|
DWORD static getHashStatic(DWORD value, DWORD type);
|
|
|
|
bool operator < (const sArrayElement &el) const;
|
|
};
|
|
|
|
class sArrayElement_HashFunc
|
|
{
|
|
public:
|
|
size_t operator() (const sArrayElement &el) const {
|
|
return el.getHash();
|
|
}
|
|
};
|
|
|
|
class sArrayElement_EqualFunc
|
|
{
|
|
public:
|
|
bool operator() (const sArrayElement &elA, const sArrayElement &elB) const;
|
|
};
|
|
|
|
struct sArrayVarOld
|
|
{
|
|
DWORD len;
|
|
DWORD datalen;
|
|
DWORD* types;
|
|
char* data;
|
|
};
|
|
|
|
#define ARRAYFLAG_ASSOC (1) // is map
|
|
#define ARRAYFLAG_CONSTVAL (2) // don't update value of key if the key exists in map
|
|
#define ARRAYFLAG_RESERVED (4)
|
|
|
|
typedef std::tr1::unordered_map<sArrayElement, DWORD, sArrayElement_HashFunc, sArrayElement_EqualFunc> ArrayKeysMap;
|
|
|
|
/**
|
|
This class represents sfall array
|
|
It can be both list (normal array) and map (associative)
|
|
|
|
TODO: rewrite for better interface (especially associate arrays)
|
|
*/
|
|
class sArrayVar
|
|
{
|
|
public:
|
|
DWORD flags;
|
|
sArrayElement key; // array associated key, if it was saved
|
|
ArrayKeysMap keyHash; // key element => element index, for faster lookup
|
|
std::vector<sArrayElement> val; // list of values or key=>value pairs (even - keys, odd - values)
|
|
|
|
sArrayVar() : flags(0), key() {}
|
|
|
|
sArrayVar(int len, int flag) : flags(flag), key() {
|
|
if (len == 0) val.reserve((flag & 0x7FFF0000) >> 16);
|
|
if (len < 0) val.reserve(20); // for assoc
|
|
}
|
|
|
|
bool isAssoc() const {
|
|
return (flags & ARRAYFLAG_ASSOC);
|
|
}
|
|
|
|
// logical array size (number of elements for normal arrays; number of key=>value pairs for associative)
|
|
int size() const {
|
|
size_t sz = val.size();
|
|
return isAssoc() ? sz / 2 : sz;
|
|
}
|
|
|
|
// usefull when filling array from within sfall code (normal lists only)
|
|
void push_back(long _value) {
|
|
if (!isAssoc()) {
|
|
val.push_back(_value);
|
|
}
|
|
}
|
|
|
|
// free memory used by strings
|
|
void clearArrayVar() {
|
|
clearAll();
|
|
key.clearData();
|
|
}
|
|
|
|
void clearRange(int from, int to = -1);
|
|
void clearAll();
|
|
};
|
|
|
|
// arrays map: arrayId => arrayVar
|
|
typedef std::tr1::unordered_map<DWORD, sArrayVar> ArraysMap;
|
|
extern ArraysMap arrays;
|
|
typedef ArraysMap::const_iterator array_citr;
|
|
typedef ArraysMap::iterator array_itr;
|
|
typedef std::pair<DWORD, sArrayVar> array_pair;
|
|
|
|
// auto-incremented ID
|
|
extern DWORD nextArrayID;
|
|
|
|
extern DWORD arraysBehavior;
|
|
|
|
// saved arrays: arrayKey => arrayId
|
|
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);
|
|
void DESetArray(int id, const DWORD* types, const char* data);
|
|
|
|
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 flags);
|
|
|
|
// same as CreateArray, but creates temporary array instead (will die at the end of the frame)
|
|
DWORD __stdcall CreateTempArray(DWORD len, DWORD flags);
|
|
|
|
// destroys array
|
|
void __stdcall FreeArray(DWORD id);
|
|
|
|
// destroy all temp arrays
|
|
void DeleteAllTempArrays();
|
|
|
|
/*
|
|
op_get_array_key can be used to iterate over all keys in associative array
|
|
*/
|
|
DWORD __stdcall GetArrayKey(DWORD id, int index, DWORD* resultType);
|
|
|
|
// get array element by index (list) or key (map)
|
|
DWORD __stdcall GetArray(DWORD id, DWORD key, DWORD keyType, DWORD* resultType);
|
|
|
|
// set array element by index or key (with checking the existence of the array ID)
|
|
void __stdcall SetArray(DWORD id, DWORD key, DWORD keyType, DWORD val, DWORD valType, DWORD allowUnset);
|
|
|
|
// set array element by index or key
|
|
void __stdcall setArray(DWORD id, DWORD key, DWORD keyType, DWORD val, DWORD valType, DWORD allowUnset);
|
|
|
|
// number of elements in list or pairs in map
|
|
int __stdcall LenArray(DWORD id);
|
|
|
|
// change array size (only works with list)
|
|
void __stdcall ResizeArray(DWORD id, int newlen);
|
|
|
|
// make temporary array persistent
|
|
void __stdcall FixArray(DWORD id);
|
|
|
|
// searches for a given element in array and returns it's index (for list) or key (for map) or int(-1) if not found
|
|
int __stdcall ScanArray(DWORD id, DWORD val, DWORD datatype, DWORD* resultType);
|
|
|
|
// get saved array by it's key
|
|
DWORD __stdcall LoadArray(DWORD key, DWORD keyType);
|
|
|
|
// make array saved into the savegame with associated key
|
|
void __stdcall SaveArray(DWORD key, DWORD keyType, DWORD id);
|
|
|
|
// special function that powers array expressions
|
|
long __stdcall StackArray(DWORD key, DWORD keyType, DWORD val, DWORD valType);
|
|
|
|
sArrayVar* __stdcall GetRawArray(DWORD id);
|