Added hashmaps

dev
Shariq Shah 9 years ago
parent faa40bb206
commit a17cb85b92
  1. 6
      orgfile.org
  2. 2
      src/array.h
  3. 33
      src/config_vars.c
  4. 13
      src/config_vars.h
  5. 253
      src/hashmap.c
  6. 39
      src/hashmap.h
  7. 4
      src/linmath.c
  8. 4
      src/linmath.h
  9. 1
      src/scene.c
  10. 75
      src/variant.c
  11. 14
      src/variant.h

@ -23,7 +23,7 @@ diffuse_color: 1 0 0 1
diffuse_texture: "checkered.tga"
specular: 0.55
*** Configuration Variables a.k.a cvars
*** Configuration Variables a.k.a cfg-vars
// Comment
render_width: 1024
render_height: 1024
@ -37,6 +37,8 @@ msaa_levels: 8
*** Keybindings
*** Level/Scene
*** Materials
*** Mesh/Geometry
* Things TODO
** DONE Input
- State "DONE" from "TODO" [2015-07-02 Thu 01:24]
@ -166,7 +168,7 @@ x Font atlas proper cleanup
- Keybindings in config
- Log output on every run.
** TODO Do input maps really need to be queried by their string names?
** TODO Reloading shaders?
** TODO Reloading all the things! (textures/shaders/models/settings/entities etc)
** TODO Separate Debug/Editor camera from the active camera in the scene that can be switched to at any time
** DONE Live data views in editor
- State "DONE" from "TODO" [2017-03-22 Wed 02:14]

@ -6,7 +6,7 @@
/* Private use */
void* array_new_(size_t object_size, int capacity);
void* array_grow_(void** array);
int array_reset_(void** array, int length); // Resize to length objects whose data is unspecified
int array_reset_(void** array, int length); // Resize to length objects whose data is unspecified, previous data is freed
int array_pop_(void** array); // Remove object with highest index
int array_remove_at_(void** array, int index);
void array_match_len_cap_(void** array);

@ -0,0 +1,33 @@
#include "config_vars.h"
#include "string_utils.h"
#include "variant.h"
#include "hashmap.h"
#include <stdlib.h>
static struct Hashmap* cvars = NULL;
void config_vars_init(void)
{
cvars = hashmap_new();
}
void config_vars_cleanup(void)
{
hashmap_free(cvars);
}
struct Hashmap* config_vars_get(void)
{
return cvars;
}
int config_vars_load(const char* filename)
{
}
void config_vars_save(const char* filename)
{
}

@ -0,0 +1,13 @@
#ifndef CONFIG_VARS_H
#define CONFIG_VARS_H
struct Hashmap;
void config_vars_init(void);
void config_vars_cleanup(void);
int config_vars_load(const char* filename);
void config_vars_save(const char* filename);
struct Hashmap* config_vars_get(void);
#endif

@ -0,0 +1,253 @@
#include "hashmap.h"
#include "array.h"
#include "variant.h"
#include "string_utils.h"
#include <stdlib.h>
#include <string.h>
#define HASH_MAP_NUM_BUCKETS 10
#define HASH_MAX_KEY_LEN 128
struct Hashmap_Entry
{
char* key;
struct Variant value;
};
struct Hashmap
{
struct Hashmap_Entry* buckets[HASH_MAP_NUM_BUCKETS];
};
static int hashmap_generate_hash(const char* key);
static struct Hashmap_Entry* hashmap_entry_new(struct Hashmap* hashmap, const char* key);
static struct Hashmap_Entry* hashmap_entry_new(struct Hashmap* hashmap, const char* key)
{
int index = hashmap_generate_hash(key);
struct Hashmap_Entry* new_entry = NULL;
for(int i = 0; i < array_len(hashmap->buckets[index]); i++) /* Look for duplicates and over-write if found */
{
if(strncmp(key, hashmap->buckets[index][i].key, HASH_MAX_KEY_LEN) == 0)
{
new_entry = &hashmap->buckets[index][i];
if(new_entry->key) free(new_entry->key);
break;
}
}
if(!new_entry) new_entry = array_grow(hashmap->buckets[index], struct Hashmap_Entry);
new_entry->key = str_new(key);
return new_entry;
}
int hashmap_generate_hash(const char* key)
{
int index = -1;
const int multiplier = 51;
for(int i = 0; i < (int)strlen(key); i++)
index = index * multiplier + key[i];
return index % HASH_MAP_NUM_BUCKETS;
}
struct Hashmap* hashmap_new(void)
{
struct Hashmap* hashmap = malloc(sizeof(*hashmap));
if(!hashmap)
return NULL;
for(int i = 0; i < HASH_MAP_NUM_BUCKETS; i++)
hashmap->buckets[i] = array_new(struct Hashmap_Entry);
return hashmap;
}
void hashmap_free(struct Hashmap* hashmap)
{
if(!hashmap) return;
for(int i = 0; i < HASH_MAP_NUM_BUCKETS; i++)
{
for(int j = 0; j < array_len(hashmap->buckets[j]); j++)
{
struct Hashmap_Entry* entry = &hashmap->buckets[i][j];
if(entry->key)
{
free(entry->key);
entry->key = NULL;
}
variant_free(&entry->value);
}
}
free(hashmap);
hashmap = NULL;
}
void hashmap_value_set(struct Hashmap* hashmap, const char* key, const struct Variant* value)
{
if(!hashmap || !key || !value) return;
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_copy(&new_entry->value, value);
}
const struct Variant* hashmap_value_get(struct Hashmap* hashmap, const char* key)
{
if(!hashmap || !key) return NULL;
struct Variant* value = NULL;
int index = hashmap_generate_hash(key);
for(int i = 0; i < array_len(hashmap->buckets[index]); i++)
{
if(strncmp(key, hashmap->buckets[index][i].key, HASH_MAX_KEY_LEN) == 0)
{
value = &hashmap->buckets[index][i].value;
break;
}
}
return value;
}
void hashmap_value_remove(struct Hashmap* hashmap, const char* key)
{
if(!hashmap || !key) return;
int index = hashmap_generate_hash(key);
int index_to_remove = -1;
for(int i = 0; i < array_len(hashmap->buckets[index]); i++)
{
if(strncmp(key, hashmap->buckets[index][i].key, HASH_MAX_KEY_LEN) == 0)
{
index_to_remove = i;
break;
}
}
if(index_to_remove != -1) array_remove_at(hashmap->buckets[index], index_to_remove);
}
void hashmap_float_set(struct Hashmap* hashmap, const char* key, float value)
{
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_assign_float(&new_entry->value, value);
}
void hashmap_int_set(struct Hashmap* hashmap, const char* key, int value)
{
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_assign_int(&new_entry->value, value);
}
void hashmap_double_set(struct Hashmap* hashmap, const char* key, double value)
{
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_assign_double(&new_entry->value, value);
}
void hashmap_bool_set(struct Hashmap* hashmap, const char* key, int value)
{
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_assign_bool(&new_entry->value, value);
}
void hashmap_vec2_set(struct Hashmap* hashmap, const char* key, const vec2* value)
{
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_assign_vec2(&new_entry->value, value);
}
void hashmap_vec3_set(struct Hashmap* hashmap, const char* key, const vec3* value)
{
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_assign_vec3(&new_entry->value, value);
}
void hashmap_vec4_set(struct Hashmap* hashmap, const char* key, const vec4* value)
{
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_assign_vec4(&new_entry->value, value);
}
void hashmap_quat_set(struct Hashmap* hashmap, const char* key, const quat* value)
{
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_assign_quat(&new_entry->value, value);
}
void hashmap_mat4_set(struct Hashmap* hashmap, const char* key, const mat4* value)
{
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_assign_mat4(&new_entry->value, value);
}
void hashmap_str_set(struct Hashmap* hashmap, const char* key, const char* value)
{
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_assign_str(&new_entry->value, value);
}
void hashmap_ptr_set(struct Hashmap* hashmap, const char* key, void* value)
{
struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key);
variant_assign_ptr(&new_entry->value, value);
}
float hashmap_float_get(struct Hashmap* hashmap, const char* key)
{
const struct Variant* variant = hashmap_value_get(hashmap, key);
return variant->val_float;
}
int hashmap_int_get(struct Hashmap* hashmap, const char* key)
{
const struct Variant* variant = hashmap_value_get(hashmap, key);
return variant->val_int;
}
double hashmap_double_get(struct Hashmap* hashmap, const char* key)
{
const struct Variant* variant = hashmap_value_get(hashmap, key);
return variant->val_double;
}
int hashmap_get_bool(struct Hashmap* hashmap, const char* key)
{
const struct Variant* variant = hashmap_value_get(hashmap, key);
return variant->val_bool;
}
vec2 hashmap_vec2_get(struct Hashmap* hashmap, const char* key)
{
const struct Variant* variant = hashmap_value_get(hashmap, key);
return variant->val_vec2;
}
vec3 hashmap_vec3_get(struct Hashmap* hashmap, const char* key)
{
const struct Variant* variant = hashmap_value_get(hashmap, key);
return variant->val_vec3;
}
vec4 hashmap_vec4_get(struct Hashmap* hashmap, const char* key)
{
const struct Variant* variant = hashmap_value_get(hashmap, key);
return variant->val_vec4;
}
quat hashmap_quat_get(struct Hashmap* hashmap, const char* key)
{
const struct Variant* variant = hashmap_value_get(hashmap, key);
return variant->val_quat;
}
const mat4* hashmap_mat4_get(struct Hashmap* hashmap, const char* key)
{
const struct Variant* variant = hashmap_value_get(hashmap, key);
return variant->val_mat4;
}
const char* hashmap_str_get(struct Hashmap* hashmap, const char* key)
{
const struct Variant* variant = hashmap_value_get(hashmap, key);
return variant->val_str;
}
void* hashmap_ptr_get(struct Hashmap* hashmap, const char* key)
{
const struct Variant* variant = hashmap_value_get(hashmap, key);
return variant->val_voidptr;
}

@ -0,0 +1,39 @@
#ifndef HASHMAP_H
#define HASHMAP_H
#include "linmath.h"
struct Hashmap;
struct Variant;
struct Hashmap* hashmap_new(void);
void hashmap_free(struct Hashmap* hashmap);
void hashmap_value_remove(struct Hashmap* hashmap, const char* key);
void hashmap_value_set(struct Hashmap* hashmap, const char* key, const struct Variant* value);
const struct Variant* hashmap_value_get(struct Hashmap* hashmap, const char* key);
void hashmap_float_set(struct Hashmap* hashmap, const char* key, float value);
void hashmap_int_set(struct Hashmap* hashmap, const char* key, int value);
void hashmap_double_set(struct Hashmap* hashmap, const char* key, double value);
void hashmap_bool_set(struct Hashmap* hashmap, const char* key, int value);
void hashmap_vec2_set(struct Hashmap* hashmap, const char* key, const vec2* value);
void hashmap_vec3_set(struct Hashmap* hashmap, const char* key, const vec3* value);
void hashmap_vec4_set(struct Hashmap* hashmap, const char* key, const vec4* value);
void hashmap_quat_set(struct Hashmap* hashmap, const char* key, const quat* value);
void hashmap_mat4_set(struct Hashmap* hashmap, const char* key, const mat4* value);
void hashmap_str_set(struct Hashmap* hashmap, const char* key, const char* value);
void hashmap_ptr_set(struct Hashmap* hashmap, const char* key, void* value);
float hashmap_float_get(struct Hashmap* hashmap, const char* key);
int hashmap_int_get(struct Hashmap* hashmap, const char* key);
double hashmap_double_get(struct Hashmap* hashmap, const char* key);
int hashmap_get_bool(struct Hashmap* hashmap, const char* key);
vec2 hashmap_vec2_get(struct Hashmap* hashmap, const char* key);
vec3 hashmap_vec3_get(struct Hashmap* hashmap, const char* key);
vec4 hashmap_vec4_get(struct Hashmap* hashmap, const char* key);
quat hashmap_quat_get(struct Hashmap* hashmap, const char* key);
const mat4* hashmap_mat4_get(struct Hashmap* hashmap, const char* key);
const char* hashmap_str_get(struct Hashmap* hashmap, const char* key);
void* hashmap_ptr_get(struct Hashmap* hashmap, const char* key);
#endif

@ -31,7 +31,7 @@ void vec2_sub(vec2* res, vec2* v1, vec2* v2)
res->y = v1->y - v2->y;
}
void vec2_assign(vec2* res, vec2* val)
void vec2_assign(vec2* res, const vec2* val)
{
res->x = val->x;
res->y = val->y;
@ -221,7 +221,7 @@ void vec4_sub(vec4* res, vec4* v1, vec4* v4)
res->w = v1->w - v4->w;
}
void vec4_assign(vec4* res, vec4* val)
void vec4_assign(vec4* res, const vec4* val)
{
res->x = val->x;
res->y = val->y;

@ -62,7 +62,7 @@ extern const vec3 UNIT_Z_NEG;
void vec2_fill(vec2* res, float x, float y);
void vec2_add(vec2* res, vec2* v1, vec2* v2);
void vec2_sub(vec2* res, vec2* v1, vec2* v2);
void vec2_assign(vec2* res, vec2* val);
void vec2_assign(vec2* res, const vec2* val);
void vec2_mul(vec2* res, vec2* v1, vec2* v2);
float vec2_len(vec2* val);void vec2_norm(vec2* res, vec2* val);
@ -91,7 +91,7 @@ void vec4_mul_mat4(vec4* res, vec4* val, mat4* mat);
void vec4_mul(vec4* res, vec4* v1, vec4* v4);
void vec4_norm(vec4* res, vec4* val);
float vec4_len(vec4* val);
void vec4_assign(vec4* res, vec4* val);
void vec4_assign(vec4* res, const vec4* val);
void vec4_sub(vec4* res, vec4* v1, vec4* v4);
void vec4_add(vec4* res, vec4* v1, vec4* v4);

@ -14,7 +14,6 @@ void scene_init(void)
/* Add root node to scene */
struct Entity* root = entity_create("ROOT", NULL);
root_node = root->node;
log_message("Root Parent : %d", root->parent);
}
struct Entity* scene_add_new(const char* name, const char* tag)

@ -8,21 +8,8 @@ void variant_init_empty(struct Variant* variant)
{
variant->type = VT_NONE;
variant->val_voidptr = NULL;
}
void variant_assign_mat4(struct Variant* variant, const mat4* source)
{
if(variant->type != VT_MAT4) variant_free(variant);
if(!variant->val_voidptr)
{
variant->val_voidptr = malloc(sizeof(mat4));
if(!variant->val_voidptr)
{
log_error("variant_init_mat4", "Out of memory");
return;
}
}
mat4_assign(variant->val_voidptr, source);
variant->val_mat4 = NULL;
variant->val_str = NULL;
}
void variant_assign_float(struct Variant* variant, float value)
@ -50,7 +37,7 @@ void variant_assign_bool(struct Variant* variant, int value)
{
if(variant->type != VT_BOOL) variant_free(variant);
variant->type = VT_BOOL;
variant->val_int = value;
variant->val_bool = value;
}
void variant_assign_str(struct Variant* variant, const char* value)
@ -60,43 +47,62 @@ void variant_assign_str(struct Variant* variant, const char* value)
variant->val_str = str_new(value);
}
void variant_assign_vec2(struct Variant* variant, vec2* value)
void variant_assign_vec2(struct Variant* variant, const vec2* value)
{
if(variant->type != VT_VEC2) variant_free(variant);
variant->type = VT_VEC2;
vec2_assign(&variant->val_vec2, value);
}
void variant_assign_vec3(struct Variant* variant, vec3* value)
void variant_assign_vec3(struct Variant* variant, const vec3* value)
{
if(variant->type != VT_VEC3) variant_free(variant);
variant->type = VT_VEC3;
vec3_assign(&variant->val_vec3, value);
}
void variant_assign_vec4(struct Variant* variant, vec4* value)
void variant_assign_vec4(struct Variant* variant, const vec4* value)
{
if(variant->type != VT_VEC4) variant_free(variant);
variant->type = VT_VEC4;
vec4_assign(&variant->val_vec4, value);
}
void variant_assign_quat(struct Variant* variant, quat* value)
void variant_assign_quat(struct Variant* variant, const quat* value)
{
if(variant->type != VT_QUAT) variant_free(variant);
variant->type = VT_QUAT;
quat_assign(&variant->val_quat, value);
}
void variant_assign_mat4(struct Variant* variant, const mat4* source)
{
if(variant->type != VT_MAT4) variant_free(variant);
variant->val_mat4 = malloc(sizeof(mat4));
if(!variant->val_mat4)
{
log_error("variant_init_mat4", "Out of memory");
return;
}
mat4_assign(variant->val_voidptr, source);
}
void variant_assign_ptr(struct Variant* variant, void* source)
{
if(variant->type != VT_VOID_PTR) variant_free(variant);
variant->type = VT_VOID_PTR;
variant->val_voidptr = source;
}
void variant_free(struct Variant* variant)
{
switch(variant->type)
{
case VT_MAT4:
if(variant->val_voidptr)
if(variant->val_mat4)
{
free(variant->val_voidptr);
variant->val_voidptr = NULL;
free(variant->val_mat4);
variant->val_mat4 = NULL;
}
break;
case VT_STR:
@ -106,8 +112,31 @@ void variant_free(struct Variant* variant)
variant->val_str = NULL;
}
break;
case VT_VOID_PTR:
variant->val_voidptr = NULL;
break;
default: /* Nothing to be done for the rest*/
break;
};
variant->type = VT_NONE;
}
void variant_copy(struct Variant* to, const struct Variant* from)
{
to->type = from->type;
switch(from->type)
{
case VT_BOOL: variant_assign_bool(to, from->val_int); break;
case VT_INT: variant_assign_int(to, from->val_bool); break;
case VT_FLOAT: variant_assign_float(to, from->val_float); break;
case VT_DOUBLE: variant_assign_double(to, from->val_double); break;
case VT_VEC2: variant_assign_vec2(to, &from->val_vec2); break;
case VT_VEC3: variant_assign_vec3(to, &from->val_vec3); break;
case VT_VEC4: variant_assign_vec4(to, &from->val_vec4); break;
case VT_QUAT: variant_assign_quat(to, &from->val_quat); break;
case VT_MAT4: variant_assign_mat4(to, from->val_mat4); break;
case VT_STR: variant_assign_str(to, from->val_str); break;
default: /* Nothing to be done for the rest*/
break;
}
}

@ -26,6 +26,7 @@ struct Variant
union
{
int val_int;
int val_bool;
float val_float;
double val_double;
char* val_str;
@ -33,21 +34,24 @@ struct Variant
vec3 val_vec3;
vec4 val_vec4;
quat val_quat;
mat4* val_mat4;
void* val_voidptr;
};
};
void variant_init_empty(struct Variant* variant);
void variant_assign_mat4(struct Variant* variant, const mat4* source);
void variant_assign_float(struct Variant* variant, float value);
void variant_assign_int(struct Variant* variant, int value);
void variant_assign_double(struct Variant* variant, double value);
void variant_assign_bool(struct Variant* variant, int value);
void variant_assign_str(struct Variant* variant, const char* value);
void variant_assign_vec2(struct Variant* variant, vec2* value);
void variant_assign_vec3(struct Variant* variant, vec3* value);
void variant_assign_vec4(struct Variant* variant, vec4* value);
void variant_assign_quat(struct Variant* variant, quat* value);
void variant_assign_vec2(struct Variant* variant, const vec2* value);
void variant_assign_vec3(struct Variant* variant, const vec3* value);
void variant_assign_vec4(struct Variant* variant, const vec4* value);
void variant_assign_quat(struct Variant* variant, const quat* value);
void variant_assign_mat4(struct Variant* variant, const mat4* source);
void variant_assign_ptr(struct Variant* variant, void* source);
void variant_copy(struct Variant* to, const struct Variant* from);
void variant_free(struct Variant* variant);
#endif

Loading…
Cancel
Save