/**************************************************************************** * element.h * This class acts as sort of an interface for storing values in the judy * arrays. By storing an 'element' with error handling and type checking, * crashes and errors are less likely. In addition, by storing the type of * data it is also possible to save or load from a file. ****************************************************************************/ #if !defined(_CLASSDEF_ELEMENT_) #define _CLASSDEF_ELEMENT_ const Vector* null_vec = new Vector(); enum { elem_type_none, //only used on init. elem_type_int, elem_type_real, elem_type_char, elem_type_vector }; const char* elem_types[] = { "-NO VALUE-", "INTEGER", "FLOAT", "STRING", "VECTOR" }; class element { public: void set_int(int Value); void set_flo(REAL Value); void set_str(char* Value); void set_vec(Vector* Value); element (int Value) { set_int(Value); } element (REAL Value) { set_flo(Value); } element (char* Value) { set_str(Value); } element (Vector* Value) { set_vec(Value); } element(void); REAL get_flo(int &error); int get_int(int &error); const char* get_str(int &error); const Vector* get_vec(int &error); int get_type(void); Pvoid_t get_ptr(void); virtual ~element(); void delete_element(void) { clear(); element::~element(); } char* get_elem_as_string(void); //This is handy because it takes all the data needed and issues the error. void issue_type_error(AMX *amx, int Keytable, char* Index); void issue_type_error(AMX *amx, int Array, int Index); private: Pvoid_t element_ptr; //Contains a pointer to whatever data is actually stored. void clear(void); char element_type; }; Pvoid_t element::get_ptr(void) { return element_ptr; } void element::issue_type_error(AMX *amx, int Keytable, char* Index) { MF_LogError(amx, AMX_ERR_NATIVE, "Function attempted to read NON-%s value at key \"%s\" in keytable %d, actual value: %s", elem_types[element_type], Index, Keytable, get_elem_as_string()); } void element::issue_type_error(AMX *amx, int Array, int Index) { MF_LogError(amx, AMX_ERR_NATIVE, "Function attempted to read NON-%s value at index %d in array %d, actual value: %s", elem_types[element_type], Index, Array, get_elem_as_string()); } char* element::get_elem_as_string(void) { char* value = ""; Vector vector_val; int error; //Is not checked. switch (element_type) { case elem_type_int: sprintf(value, "%d", get_int(error)); break; case elem_type_real: sprintf(value, "%f", get_int(error)); break; case elem_type_char: sprintf(value, "\"%s\"", get_str(error)); break; case elem_type_vector: vector_val = *get_vec(error); sprintf(value, "{%f,%f,%f}", vector_val.x, vector_val.y, vector_val.z); break; default: sprintf(value, "-NO VALUE-"); } return value; } REAL element::get_flo(int &error) { if (element_type == elem_type_real) return *reinterpret_cast(element_ptr); error = 1; return 0; } int element::get_int(int &error) { if (element_type == elem_type_int) return reinterpret_cast(element_ptr); error = 1; return 0; } const char* element::get_str(int &error) { if (element_type == elem_type_char) return reinterpret_cast(element_ptr); error = 1; return ""; } const Vector* element::get_vec(int &error) { if (element_type == elem_type_vector) return reinterpret_cast(element_ptr); error = 1; return null_vec; } int element::get_type(void) { return element_type; } element::element() { } void element::set_int(int Value) { clear(); element_type = elem_type_int; element_ptr = reinterpret_cast(Value); //Don't need to make it a pointer to an int here. } void element::set_flo(REAL Value) { clear(); element_type = elem_type_real; element_ptr = new REAL(Value); } void element::set_str(char* Value) { clear(); element_type = elem_type_char; char *string_val = new char[strlen(Value)+1]; strcpy(string_val,Value); element_ptr = reinterpret_cast(string_val); } void element::set_vec(Vector* Value) { clear(); element_type = elem_type_vector; element_ptr = reinterpret_cast(Value); } element::~element() { //do nothing here or else data WILL be lost. } void element::clear() { //This function intelligently creates a pointer x, //which will be of correct type and then deletes it. if (element_type == elem_type_real) { REAL *real_val = reinterpret_cast(element_ptr); delete real_val; //This is actually a pointer to the float/double. } else if (element_type == elem_type_char) { char *char_val = reinterpret_cast(element_ptr); delete char_val; //Again, cast a pointer. } else if (element_type == elem_type_vector) { Vector *vector_val = reinterpret_cast(element_ptr); delete vector_val; //And again. } element_ptr = NULL; //Null the address as well. (Used for ints too.) } #endif // !defined(_CLASSDEF_ELEMENT_)