Sepehr Taghdisian avatar Sepehr Taghdisian committed 27e9647

added wscripts, restructures project dirs

Comments (0)

Files changed (244)

3rdparty/assimp/src/wscript

 import os
 
 def build(bld):
-    bld.env.append_unique("INCLUDES", 
+    if bld.env.DEBUG:
+        env = bld.all_envs["3rdparty_debug"].derive()
+    else:
+        env = bld.all_envs["3rdparty"].derive()
+    
+    env.append_unique("INCLUDES", 
         [os.path.normpath(bld.path.abspath() + "/../../include"), 
          os.path.normpath(bld.path.abspath() + "/BoostWorkaround")])
-    bld.env.append_unique("DEFINES", "ASSIMP_BUILD_BOOST_WORKAROUND")
+    env.append_unique("DEFINES", "ASSIMP_BUILD_BOOST_WORKAROUND")
     
     # remove no-rtti
-    if "-fno-rtti" in bld.env.CXXFLAGS:
-        del bld.env.CXXFLAGS[bld.env.CXXFLAGS.index("-fno-rtti")]
+    if "-fno-rtti" in env.CXXFLAGS:
+        del env.CXXFLAGS[env.CXXFLAGS.index("-fno-rtti")]
     
-    if bld.env.PLATFORM != "WIN":
-        bld.env.append_unique("CXXFLAGS", "-fvisibility=hidden")
-    
+    if env.PLATFORM != "WIN":
+        env.append_unique("CXXFLAGS", "-fvisibility=hidden")
+        
     files = []
     
-    ##########
-    # contrib
+    # contrib sources
     files.extend(bld.path.ant_glob("contrib/clipper/*.cpp"))
-    files.extend(bld.path.ant_glob("contrib/ConvertUTF/*.cpp"))
-    #files.extend(bld.path.ant_glob("contrib/cppunit-1.12.1/src/cppunit/*.c*"))
+    files.extend(bld.path.ant_glob("contrib/ConvertUTF/*.c"))
     files.extend(bld.path.ant_glob("contrib/irrXML/*.c*"))
     files.extend(bld.path.ant_glob("contrib/poly2tri/poly2tri/common/*.c*"))
     files.extend(bld.path.ant_glob("contrib/poly2tri/poly2tri/sweep/*.c*"))  
     files.extend(bld.path.ant_glob("contrib/unzip/*.c"))
-    #files.extend(bld.path.ant_glob("contrib/zlib/*.c"))
     
     # main source
     files.extend(bld.path.ant_glob("*.c*"))
     
     #
-    target_name = "assimp" + bld.env.SUFFIX
-    
     bld.shlib(
-        source=files,
-        target=target_name,
-        name="3rdparty_assimp",
-        install_path="${BINDIR}")
+        source = files,
+        target = "assimp" + env.SUFFIX,
+        install_path = "${INSTALLDIR}",
+        env = env,
+        use = ["z" + env.SUFFIX])

3rdparty/cjson/src/wscript

 #! /usr/bin/env python
 
 def build(bld):
+    if bld.env.DEBUG:
+        env = bld.all_envs["3rdparty_debug"].derive()
+    else:
+        env = bld.all_envs["3rdparty"].derive()
+            
     files = ["cJSON.c"]
         
-    bld.stlib(source = files,
-              name = "3rdparty_cjson",
-              target = "cjson" + bld.env.SUFFIX,
-              install_path = "${LIBDIR}")
+    bld.stlib(
+            env = env,
+            source = files,
+            target = "cjson" + env.SUFFIX,
+            install_path = "${LIBDIR}")
     

3rdparty/efsw/FileWatcher.cpp

 #else
 #	define FILEWATCHER_IMPL FileWatcherGeneric
 #	define BACKEND_NAME "Generic"
-#endif
+#endif 
 
 #include <efsw/Debug.hpp>
 

3rdparty/efsw/wscript

 #! /usr/bin/env python
 
 def build(bld):
+    if bld.env.DEBUG:
+        env = bld.all_envs["3rdparty_debug"].derive()
+    else:
+        env = bld.all_envs["3rdparty"].derive()
+    
     files = [
         "Debug.cpp",
         "DirectorySnapshot.cpp",
         "WatcherKqueue.cpp",
         "WatcherWin32.cpp"]
     
-    if bld.env.PLATFORM == "WIN":
+    if env.PLATFORM == "WIN":
         files.extend([
             "platform/win/FileSystemImpl.cpp",
             "platform/win/MutexImpl.cpp",
             "platform/posix/SystemImpl.cpp",
             "platform/posix/ThreadImpl.cpp"])
     
-    bld.env.append_unique("DEFINES", "EFSW_EXPOSTS")
-    bld.env.append_unique("INCLUDES", ["../include", ".."])
+    env.append_unique("DEFINES", "EFSW_EXPOSTS")
+    env.append_unique("INCLUDES", ["../include", ".."])
     
-    target_name = "efsw" + bld.env.SUFFIX
-    bld.shlib(source=files,
-            name="3rdparty_efsw",
-            target=target_name,
-            install_path="${BINDIR}")
+    bld.shlib(
+        env = env,
+        source = files,
+        target = "efsw" + env.SUFFIX,
+        install_path = "${INSTALLDIR}")

3rdparty/ezxml/src/wscript

 #! /usr/bin/env python
 
 def build(bld):
+    if bld.env.DEBUG:
+        env = bld.all_envs["3rdparty_debug"].derive()
+    else:
+        env = bld.all_envs["3rdparty"].derive()
+            
     files = ["ezxml.c"]
-    target_name = "ezxml" + bld.env.SUFFIX
     
     bld.stlib(
+        env = env,
         source = files,
-        name = "3rdparty_ezxml",
         install_path = "${LIBDIR}",
-        target = target_name)
+        target = "ezxml" + env.SUFFIX)
     

3rdparty/gl3w/src/wscript

 #! /usr/bin/env python
 
 def build(bld):
+    if bld.env.DEBUG:
+        env = bld.all_envs["3rdparty_debug"].derive()
+    else:
+        env = bld.all_envs["3rdparty"].derive()
+    
     files = ["gl3w.c"]
-    target_name = "gl3w" + bld.env.SUFFIX
-    bld.env.append_unique("INCLUDES", "../include")
+    env.append_unique("INCLUDES", env.ROOTDIR + "/3rdparty/gl3w/include")
     
     bld.stlib(
         source = files,
-        name = "3rdparty_gl3w",
         install_path = "${LIBDIR}",
-        target = target_name)
+        target = "gl3w" + env.SUFFIX,
+        env = env)

3rdparty/lua/src/wscript

 #! /usr/bin/env python
 
 def build(bld):
+    if bld.env.DEBUG:
+        env = bld.all_envs["3rdparty_debug"].derive()
+    else:
+        env = bld.all_envs["3rdparty"].derive()
+            
     files = bld.path.ant_glob("*.c")
-    target_name = "lua" + bld.env.SUFFIX
     
     bld.stlib(
+        env = env,
         source = files,
-        name = "3rdparty_lua",
         install_path = "${LIBDIR}",
-        target = target_name)
+        target = "lua" + env.SUFFIX)
     
 
     

3rdparty/mongoose/src/wscript

 #! /usr/bin/env python
 
 def build(bld):
+    if bld.env.DEBUG:
+        env = bld.all_envs["3rdparty_debug"].derive()
+    else:
+        env = bld.all_envs["3rdparty"].derive()
+    
     files = ["mongoose.c"]
-    target_name = "mongoose" + bld.env.SUFFIX
+    target_name = "mongoose" + env.SUFFIX
     
     bld.stlib(
         source = files,
-        name = "3rdparty_mongoose",
         install_path = "${LIBDIR}",
-        target = target_name)
+        target = target_name,
+        env = env)

3rdparty/nvtt/src/wscript

 #! /usr/bin/env python
 
+def configure(cfg):
+    cfg.check(header_name="stdarg.h", features="c cprogram", mandatory=False)
+    cfg.check(header_name="unistd.h", features="c cprogram", mandatory=False)
+    cfg.check(header_name="signal.h", features="c cprogram", mandatory=False)
+    cfg.check(header_name="malloc.h", features="c cprogram", mandatory=False)
+    cfg.check(header_name="execinfo.h", features="c cprogram", mandatory=False)
+    
+    cfg.write_config_header("nvconfig.h")       
+
 def build(bld):
-    if "-fno-exceptions" in bld.env.CXXFLAGS:
-        del bld.env.CXXFLAGS[bld.env.CXXFLAGS.index("-fno-exceptions")]
+    if bld.env.DEBUG:
+        env = bld.all_envs["3rdparty_debug"].derive()
+    else:
+        env = bld.all_envs["3rdparty"].derive()
+    
+    if "-fno-exceptions" in env.CXXFLAGS:
+        del env.CXXFLAGS[env.CXXFLAGS.index("-fno-exceptions")]
 
     files = []
     
     files.extend(bld.path.ant_glob("nvimage/*.c*", excl=["nvimage/ConeMap.cpp"]))
 
     # nvtt/cuda
-    files.extend(bld.path.ant_glob("nvtt/cude/*.c*"))
+    files.extend(bld.path.ant_glob("nvtt/cuda/*.cpp"))
     
     # nvtt/squish
     files.extend(bld.path.ant_glob("nvtt/squish/*.c*", 
     # nvtt
     files.extend(bld.path.ant_glob("nvtt/*.c*"))
     
-    ####
-    bld.env.append_unique("INCLUDES", bld.path.abspath())
-    bld.env.append_unique("INCLUDES", ".")
-    bld.env.append_unique("INCLUDES", bld.path.abspath() + "/nvtt/squish")
+    # libs
+    if env.PLATFORM != "WIN":
+        env.append_unique("LIB", "dl")
+    
+    # includes
+    env.append_unique("INCLUDES", [
+        bld.path.abspath(),
+        bld.path.abspath() + "/nvtt/squish",
+        env.ROOTDIR + "/build/3rdparty/nvtt/src"])
 
-    target_name = "nvtt" + bld.env.SUFFIX
-    
     bld.shlib(
         source = files,
-        name = "3rdparty_nvtt",
-        install_path = "${BINDIR}",
-        target = target_name)
+        install_path = "${INSTALLDIR}",
+        target = "nvtt" + env.SUFFIX,
+        env = env)
     
     
     

3rdparty/sfmt/src/wscript

 #! /usr/bin/env python
 
 def build(bld):
+    if bld.env.DEBUG:
+        env = bld.all_envs["3rdparty_debug"].derive()
+    else:
+        env = bld.all_envs["3rdparty"].derive()
+    
     files = ["SFMT.c"]
-    target_name = "sfmt" + bld.env.SUFFIX
-    bld.env.append_unique("DEFINES", "MEXP=607")
+    env.append_unique("DEFINES", "MEXP=607")
     
     bld.stlib(
         source = files,
-        name = "3rdparty_sfmt",
         install_path = "${LIBDIR}",
-        target = target_name)
+        target = "sfmt" + env.SUFFIX,
+        env = env)

3rdparty/stb_image/src/wscript

 #! /usr/bin/env python
 
 def build(bld):
+    if bld.env.DEBUG:
+        env = bld.all_envs["3rdparty_debug"].derive()
+    else:
+        env = bld.all_envs["3rdparty"].derive()
+            
     files = ["stb_image.c", 
              "stb_image_write.c"]
-    target_name = "stb_image" + bld.env.SUFFIX
-    bld.env.append_unique("DEFINES", "MEXP=607")
     
     bld.stlib(
+        env = env,
         source = files,
-        name = "3rdparty_stbimage",
         install_path = "${LIBDIR}",
-        target = target_name)
+        target = "stb_image" + env.SUFFIX)

3rdparty/zlib/src/wscript

 #! /usr/bin/env python
 
 def build(bld):
+    if bld.env.DEBUG:
+        env = bld.all_envs["3rdparty_debug"].derive()
+    else:
+        env = bld.all_envs["3rdparty"].derive()
+    
     bld(features="subst", source="zconf-vs.h", target="zconf.h", is_copy=True)
     files = bld.path.ant_glob("*.c")
-    target_name = "zlib" + bld.env.SUFFIX
     
     bld.stlib(
-        source=files,
-        target=target_name,
-        name="3rdparty_zlib",
-        install_path="${LIBDIR}")
+        env = env,
+        source = files,
+        target = "z" + env.SUFFIX,
+        install_path = "${LIBDIR}")

3rdparty/zlib/src/zlib.h

 #ifndef ZLIB_H
 #define ZLIB_H
 
-#if defined(_MSC_VER)
 #include "zconf-vs.h"
-#else
-#include "zconf.h"
-#endif
 
 #ifdef __cplusplus
 extern "C" {
Add a comment to this file

build/3rdparty/debug/.dummy

Empty file removed.

Add a comment to this file

build/3rdparty/release/.dummy

Empty file removed.

Add a comment to this file

build/hmr/debug/.dummy

Empty file removed.

Add a comment to this file

build/hmr/pyengine/.dummy

Empty file removed.

Add a comment to this file

build/hmr/release/.dummy

Empty file removed.

include/core/allocator.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+
+#ifndef __ALLOCATOR_H__
+#define __ALLOCATOR_H__
+
+#include "types.h"
+
+ /**
+ * Callback function for custom allocation 
+ * @param size size (in bytes) to allocate
+ * @param source source file of allocation call
+ * @param line line number of the allocation call
+ * @param id memory id
+ * @param param void pointer to allocator structure (or any other custom parameter)
+ * @return returns pointer to allocated block
+ * @ingroup mem
+ */
+typedef void* (*pfn_alloc)(size_t size, const char* source, 
+                           uint32 line, uint32 id, void* param);
+/**
+ * Callback function for custom free
+ * @ingroup mem
+ */
+typedef void  (*pfn_free)(void* ptr, void* param);
+/**
+ * callback function for aligned allocation
+ * @see pfn_alloc @ingroup mem
+ */
+typedef void* (*pfn_alignedalloc)(size_t size, uint8 alignment, 
+                                  const char* source, uint32 line, uint32 id,
+                                  void* param);
+/**
+ * Callback function for aligned free
+ * @see pfn_free @ingroup mem
+ */
+typedef void  (*pfn_alignedfree)(void* ptr, void* param);
+
+/**
+ * Allocator structure that holds all callback functions\n
+ * each custom allocator, has a function for binding allocator structure to it's routines
+ * @see mem_stack_bindalloc @ingroup mem
+ */
+struct allocator
+{
+    pfn_alloc           alloc_fn;
+    pfn_free            free_fn;
+    pfn_alignedalloc    alignedalloc_fn;
+    pfn_alignedfree     alignedfree_fn;
+    void*               param;            /* mostly allocator source object */
+};
+
+/**
+ * Allocation with custom allocator 
+ * @param alloc custom allocator pointer
+ * @param size size of the requested memory block
+ * @param ID of the memory block
+ * @ingroup mem
+ */
+#define A_ALLOC(alloc, size, id)   \
+    (alloc)->alloc_fn((size), __FILE__, __LINE__, (id), (alloc)->param)
+/**
+ * Free memory with custom allocator
+ * @param alloc custom allocator pointer
+ * @param ptr pointer to the allocated memory @see A_ALLOC
+ * @ingroup mem
+ */
+#define A_FREE(alloc, ptr)  (alloc)->free_fn((ptr), (alloc)->param)
+/**
+ * Aligned memory allocator (16-byte)
+ * @see A_ALLOC
+ * @ingroup mem
+ */
+#define A_ALIGNED_ALLOC(alloc, size, id)    \
+    (alloc)->alignedalloc_fn((size), 16, __FILE__, __LINE__, (id), (alloc)->param)
+/**
+ * Aligned memory free
+ * @see A_ALIGNED_ALLOC
+ * @ingroup mem
+ */
+#define A_ALIGNED_FREE(alloc, ptr)  (alloc)->alignedfree_fn((ptr), (alloc)->param)
+
+#endif /*__ALLOCATOR_H__*/

include/core/array.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+#ifndef __ARRAY_H__
+#define __ARRAY_H__
+
+#include "types.h"
+#include "core-api.h"
+#include "allocator.h"
+
+/**
+ * @defgroup array Array: containers
+ * Expanding array\n
+ * holds a buffer and it's properties for expansion on demand\n
+ * Usage example:\n
+ * @code
+ * struct array myarr;
+ * arr_create(mem_heap(), &myarr, sizeof(uint32), 100, 200, 0);
+ * printf("adding numbers\n");
+ * for (uint32 i = 0; i < 10; i++)  {
+ *      uint32* pval = arr_add(&myarr);
+ *      *paval = i;
+ * }
+ * printf("listing numbers ...\n");
+ * for (uint32 i = 0; i < 10; i++)  {
+ *      printf("%d\n", ((uint32*)myarr.buffer)[i]);
+ * }
+ * arr_destroy(&myarr);
+ * @endcode
+ * @ingroup array
+ */
+struct array
+{
+    struct allocator*   alloc;      /**< allocator */
+    void*               buffer;     /**< array buffer, can be casted to any pointer type for use */
+    uint32              item_cnt;   /**< current item count in the array */
+    uint32              max_cnt;    /**< maximum item count */
+    uint32              item_sz;    /**< item size in bytes */
+    uint32              mem_id;     /**< memory id */
+    uint32              expand_sz;  /**< in number of items */
+};
+
+#ifdef __cplusplus
+extern "C"  {
+#endif
+
+/**
+ * creates an array
+ * @param alloc internal memory allocator for array data
+ * @param arr array to be created
+ * @param item_sz each array element item size (in bytes)
+ * @param init_item_cnt initial item count 
+ * @param expand_cnt number of items to expand if needed 
+ * @see arr_expand
+ * @ingroup cnt
+ */
+CORE_API result_t arr_create(struct allocator* alloc, 
+                             struct array* arr, 
+                             uint32 item_sz, uint32 init_item_cnt, uint32 expand_cnt,
+                             uint32 mem_id);
+/**
+ * destroys array
+ * @ingroup array
+ */
+CORE_API void arr_destroy(struct array* arr);
+
+/**
+ * expand the array buffer by the size defined in arr_create\n
+ * recommended method is to check to array expansion before adding new items\n
+ * example: if (arr_needexpand(a))  arr_expand(a)\n
+ *          a.buffer[a.item_cnt++] = item
+ * @see arr_needexpand  @see arr_create @ingroup array
+ */ 
+CORE_API result_t arr_expand(struct array* arr);
+
+/**
+ * helper array function for expanding buffer, useful for adding objects
+ * expands if needed and returns newly created buffer, and adds item count to array
+ * @return newly created pointer to last item in the buffer, =NULL if out of memory
+ */
+CORE_API void* arr_add(struct array* arr);
+
+/**
+ * checks if array needs expansion
+ * @see arr_expand   @ingroup array
+ */
+INLINE bool_t arr_needexpand(const struct array* arr)
+{
+    return (arr->max_cnt == arr->item_cnt);
+}
+
+/**
+ * checks if array is empty
+ * @ingroup array
+ */
+INLINE bool_t arr_isempty(const struct array* arr)
+{
+    return (arr->item_cnt == 0);
+}
+
+/**
+ * clear array items, but does not free or resize it's buffer
+ * @ingroup array
+ */
+INLINE void arr_clear(struct array* arr)
+{
+    arr->item_cnt = 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__ARRAY_H__*/

include/core/atomic.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+#ifndef __ATOMIC_H__
+#define __ATOMIC_H__
+
+/**
+ * @defgroup atomic Atomic: multi-task
+ */
+ 
+ /**
+ * Atomic operations (wrappers)\n
+ * atomic types should be one of atomiint_t or atomptr_t types\n
+ * here are the atomic macros:\n
+ * ATOMIC_CAS(dest_ptr, cmp_value, swap_value): compare-and-swap, returns original value\n
+ * ATOMIC_SET(dest_ptr, value): set atomic value\n
+ * ATOMIC_INCR(dest_ptr) : increment atomic, returns new value\n
+ * ATOMIC_DECR(dest_ptr): decrements atomic, returns new value\n
+ * ATOMIC_CAS_PTR(dest, cmp_ptr, new_ptr): compare-and-swap pointer, returns original value\n
+ * ATOMIC_SET_PTR(dest, ptr): set atomic pointer\n
+ * @ingroup atomic
+ */
+typedef long volatile       atomint_t;
+/**
+ * @ingroup atomic
+ */
+typedef void* volatile      atomptr_t;
+
+#if defined(_WIN_)
+/* windows specific */
+#include <intrin.h>
+#define ATOMIC_CAS(dest, cmp_value, swap_value)     \
+    _InterlockedCompareExchange(&(dest), (swap_value), (cmp_value))
+#define ATOMIC_SET(dest, value)     \
+    _InterlockedExchange(&(dest), (value))
+#define ATOMIC_INCR(dest)   \
+    _InterlockedIncrement(&(dest))
+#define ATOMIC_DECR(dest_ptr)   \
+    _InterlockedDecrement(&(dest))
+#define ATOMIC_CAS_PTR(dest, cmp, new_ptr)  \
+    InterlockedCompareExchangePointer(&(dest), (new_ptr), (cmp))
+#define ATOMIC_SET_PTR(dest, ptr)   \
+    InterlockedExchangePointer(&(dest), (ptr))
+#elif defined(_LINUX_)
+/* unix/linux specific */
+#define ATOMIC_CAS(dest, cmp_value, swap_value)     \
+    __sync_val_compare_and_swap(&(dest), (cmp_value), (swap_value))
+#define ATOMIC_SET(dest, value)     \
+    __sync_lock_test_and_set(&(dest), (value))
+#define ATOMIC_INCR(dest)   \
+    _sync_add_and_fetch(&(dest), 1)
+#define ATOMIC_DECR(dest)   \
+    __sync_sub_and_fetch(&(dest), 1)
+#define ATOMIC_CAS_PTR(dest, cmp, new_ptr)  \
+	__sync_val_compare_and_swap(&(dest), (cmp), (new_ptr))
+#define ATOMIC_SET_PTR(dest, ptr) \
+	__sync_lock_test_and_set(&(dest), (ptr))
+#endif
+    
+#endif /*__ATOMIC_H__*/

include/core/color.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+
+#ifndef __COLOR_H__
+#define __COLOR_H__
+
+#include "types.h"
+#include "memory.h"
+#include <math.h>
+
+struct ALIGN16 color
+{
+    union   {
+        struct {
+            fl32 r;
+            fl32 g;
+            fl32 b;
+            fl32 a;
+        };
+
+        fl32 f[4];
+    };
+};
+
+/* globals */
+static const struct color g_color_blue = {0.0f, 0.0f, 1.0f, 1.0f};
+static const struct color g_color_red = {1.0f, 0.0f, 0.0f, 1.0f};
+static const struct color g_color_green = {0.0f, 1.0f, 0.0f, 1.0f};
+static const struct color g_color_white = {1.0f, 1.0f, 1.0f, 1.0f};
+static const struct color g_color_black = {0.0f, 0.0f, 0.0f, 1.0f};
+static const struct color g_color_grey = {0.3f, 0.3f, 0.3f, 1.0f};
+static const struct color g_color_yellow = {1.0f, 1.0f, 0.0f, 1.0f};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+INLINE bool_t color_isequal(const struct color* c1, const struct color* c2)
+{
+    return (c1->r == c2->r) && (c1->g == c2->g) && (c1->b == c2->b) && (c1->a == c2->a);
+}
+
+INLINE struct color* color_setf(struct color* c, fl32 r, fl32 g, fl32 b, fl32 a)
+{
+    c->r = r;
+    c->g = g;
+    c->b = b;
+    c->a = a;
+    return c;
+}
+
+/* rgba values are between 0~255 range */
+INLINE struct color* color_seti(struct color* c, uint8 r, uint8 g, uint8 b, uint8 a)
+{
+    c->r = ((fl32)r)/255.0f;
+    c->g = ((fl32)g)/255.0f;
+    c->b = ((fl32)b)/255.0f;
+    c->a = ((fl32)a)/255.0f;
+    return c;
+}
+
+INLINE struct color* color_setc(struct color* r, const struct color* c)
+{
+    r->r = c->r;
+    r->g = c->g;
+    r->b = c->b;
+    r->a = c->a;
+    return r;
+}
+
+INLINE uint32 color_rgba_uint(const struct color* c)
+{
+    uint8 r = (uint8)(c->r*255.0f);
+    uint8 g = (uint8)(c->g*255.0f);
+    uint8 b = (uint8)(c->b*255.0f);
+    uint8 a = (uint8)(c->a*255.0f);
+    return (uint32)((((r)&0xff)<<24) | (((g)&0xff)<<16) | (((b)&0xff)<<8) | ((a)&0xff));
+}
+
+INLINE uint32 color_rgb_uint(const struct color* c)
+{
+    uint8 r = (uint8)(c->r*255.0f);
+    uint8 g = (uint8)(c->g*255.0f);
+    uint8 b = (uint8)(c->b*255.0f);
+    return (uint32)((((r)&0xff)<<24) | (((g)&0xff)<<16) | (((b)&0xff)<<8) | 0xff);
+}
+
+INLINE struct color* color_tolinear(struct color* r, const struct color* c)
+{
+    r->r = c->r*c->r;
+    r->g = c->g*c->g;
+    r->b = c->b*c->b;
+    r->a = c->a;
+    return r;
+}
+
+INLINE struct color* color_togamma(struct color* r, const struct color* c)
+{
+    r->r = sqrtf(c->r);
+    r->g = sqrtf(c->g);
+    r->b = sqrtf(c->b);
+    r->a = c->a;
+    return r;
+}
+
+INLINE struct color* color_muls(struct color* r, const struct color* c, fl32 k)
+{
+    r->r = c->r * k;
+    r->g = c->g * k;
+    r->b = c->b * k;
+    r->a = c->a;
+    return r;
+}
+
+INLINE struct color* color_swizzle_abgr(struct color* r, const struct color* c)
+{
+    return color_setf(r, c->a, c->b, c->g, c->r);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COLOR_H */

include/core/core-api.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+
+#ifndef __COREAPI_H__
+#define __COREAPI_H__
+
+#include "types.h"
+
+#if defined(_CORE_EXPORT_)
+    #if defined(_MSVC_)
+    	#define CORE_API __declspec(dllexport)
+    #elif defined(_GNUC_)
+    	#define CORE_API __attribute__((visibility("default")))
+    #endif
+#else
+    #if defined(_MSVC_)
+    	#define CORE_API __declspec(dllimport)
+    #elif defined(_GNUC_)
+    	#define CORE_API __attribute__((visibility("default")))
+    #endif
+#endif /* defined(_CORE_EXPORT) */
+
+#if defined(SWIG)
+#define CORE_API 
+#endif
+
+#endif /* __COREAPI_H__*/

include/core/core.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+#ifndef __CORE_H__
+#define __CORE_H__
+
+/**
+ * @mainpage Core library API reference
+ * Current version: 0.4.0
+ */
+ 
+ /**
+ * @defgroup core
+ * Core library essential headers and init/release\n
+ * Include "core.h" and use core_init, core_release to initialize basic core functionality
+ * Example: @code
+ * #include "core/core.h"
+ * int main()
+ * {
+ *      core_init(TRUE);
+ *      // continue with application and engine initialization and update
+ *      core_release();
+ * }
+ * @endcode
+ */
+ 
+ /* essential headers */
+#include <stdio.h>
+
+#include "types.h"
+#include "memory.h"
+#include "errors.h"
+#include "log.h"
+#include "core-api.h"
+#include "numeric.h"
+#include "str.h"
+#include "allocator.h"
+#include "util.h"
+
+#ifdef __cplusplus
+extern "C"  {
+#endif
+
+/**
+ * Initializes/releases main 'core' components\n
+ * It initializes following core library sub-systems:
+ * - memory
+ * - logger
+ * - error handling
+ * - random
+ * - json
+ * - file-manager
+ * - timer-manager
+ * @ingroup core
+ */
+CORE_API result_t core_init(bool_t trace_mem);
+
+/**
+ * Release core components
+ * @param report_leaks report memory leaks to the logger
+ * @ingroup core
+ */
+CORE_API void core_release(bool_t report_leaks);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_H__ */

include/core/error-codes.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+#ifndef __ERRORCODES_H__
+#define __ERRORCODES_H__
+
+
+ /* error codes */
+#define RET_ABORT           2
+#define RET_OK              1
+#define RET_FAIL            0
+#define RET_OUTOFMEMORY     -1
+#define RET_WARNING         -2
+#define RET_INVALIDARG      -3
+#define RET_FILE_ERROR      -4
+#define RET_NOT_IMPL        -5
+#define RET_NOT_SUPPORTED   -6
+#define RET_INVALIDCALL		-7
+
+/* macros to check for error codes */
+#define IS_FAIL(r)      ((r) <= 0)
+#define IS_OK(r)        ((r) > 0)
+
+#endif /* __ERRORCODES_H__ */

include/core/errors.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+/**
+ * @defgroup err Error handling
+ * Ehen calling internal functions, most of them will return 'result_t' type.\n
+ * if error occurs within any function within engine, an error-stack will be created and result_t will not return RET_OK\n
+ * To check if result_t is an error, use **IS_FAIL(r)** or **IS_OK(r)** macros.\n
+ * Example:\n @code
+ *  void my_function()  {
+ *      result_t r = some_engine_func();
+ *      if (IS_FAIL(r))  {
+ *           err_print(__FILE__, __LINE__, "Error occured");
+ *           return FALSE;
+ *      }
+ *  }
+ *
+ *  void parent_function()   {
+ *      if (!my_function()) {
+ *          // send error to console and exit
+ *          printf("dark-hammer engine error: %s\n", err_getstring());
+ *          exit(-1);
+ *      }
+ *  }
+ * @endcode
+ */
+
+#ifndef __ERRORS_H__
+#define __ERRORS_H__
+
+#include "types.h"
+#include "core-api.h"
+
+#if defined(_ENABLEASSERT_)
+
+#if defined(ASSERT)
+#undef ASSERT
+#endif
+
+#if defined(_MSVC_)
+#define DEBUG_BREAK()   __debugbreak();
+#elif defined(_GNUC_)  
+#define DEBUG_BREAK()   __builtin_trap();
+#endif
+#define ASSERT(expr)    \
+    if (!(expr))    {   err_reportassert(#expr, __FILE__, __LINE__);     DEBUG_BREAK();  }
+#else
+#define ASSERT(expr)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Assertion */
+CORE_API void err_reportassert(const char* expr, const char* source, uint32 line);
+
+/**
+ * Error handling initialization
+ * @ingroup err
+ */
+CORE_API result_t err_init();
+/**
+ * error handling release
+ * @ingroup err
+ */
+CORE_API void err_release();
+
+/**
+ * print formatted and add item to error-stack
+ * @param source source file of error occurance
+ * @param line line of error occurance
+ * @param fmt formatted string
+ * @ingroup err
+ */
+CORE_API void err_printf(const char* source, uint32 line, const char* fmt, ...);
+/**
+ * print text and add item to error-stack
+ * @param source source file of error occurance
+ * @param line line of error occurance
+ * @param text error string
+ * @ingroup err
+ */
+CORE_API void err_print(const char* source, uint32 line, const char* text);
+
+/**
+ * print common error code descriptions to the error-stack
+ * @param source source file of error occurance
+ * @param line line of error occurance
+ * @param err_code error code, usually is casted from result_t
+ * @ingroup err
+ */
+CORE_API result_t err_printn(const char* source, uint32 line, uint32 err_code);
+
+/**
+ * returns last error code, and **does not clear** error-stack
+ * @ingroup err
+ */
+CORE_API uint32 err_getcode();
+
+/**
+ * sends error descriptions and call-stack to logger, **clears** the error-stack after call
+ * @param as_warning send error as warning
+ * @ingroup err
+ */
+CORE_API void err_sendtolog(bool_t as_warning);
+/**
+ * returns error descriptions and call-stack to the caller, **clears** the error-stack after call
+ * @return string buffer 
+ * @see err_sendtolog   @ingroup err
+ */
+CORE_API const char* err_getstring();
+/**
+ * clears error-stack without output to anything
+ * @see err_sendtolog @see err_getstring @ingroup err
+ */
+CORE_API void err_clear();
+/**
+ * checks if we have errors in the error-stack @ingroup err
+ */
+CORE_API bool_t err_haserrors();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ERRORS_H__ */

include/core/file-mgr.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+
+#ifndef __FILEMGR_H__
+#define __FILEMGR_H__
+
+#ifdef __cplusplus
+extern "C"  {
+#endif
+
+#include "types.h"
+#include "core-api.h"
+#include "allocator.h"
+#include "pool-alloc.h"
+#include "array.h"
+
+/**
+ * @defgroup fileio File manager: file-system
+ */
+
+#define FILE_NULL   NULL
+
+/* fwd declarations */
+struct pak_file;
+
+/**
+ * @ingroup fileio
+ */
+typedef void (*pfn_filechange_callback)(const char* filepath, reshandle_t hdl, uptr_t param1, 
+    uptr_t param2);
+
+/**
+ * Basic file type, used in file io functions, if =FILE_NULL then it is either invalid or not created
+ * @ingroup fileio
+ */
+typedef void*   file_t;
+
+/**
+ * @see io_file_seek @ingroup fileio
+ */
+enum seek_mode
+{
+    SEEK_MODE_START,    /**< seek from the beginning of the file */
+    SEEK_MODE_END, /**< seek from the end of the file */
+    SEEK_MODE_CUR /**< seek from the current position of the file */
+};
+
+/**
+ * @ingroup fileio
+ */
+enum file_type
+{
+    FILE_TYPE_MEM, /**< file resides in memory */
+    FILE_TYPE_DSK /**< file resides on disk */
+};
+
+/**
+ * @ingroup fileio
+ */
+enum file_mode
+{
+    FILE_MODE_WRITE, /**< file is opened for writing */
+    FILE_MODE_READ /**< file is opened for reading */
+};
+
+result_t io_initfilemgr();
+void io_releasefilemgr();
+
+/**
+ * Add virtual-directory to the virtual-filesystem \n
+ * Example usage:\n
+ * @code
+ * io_addvdir("d:\\mygame\\data\\");
+ * io_file_opendisk("textures\\hello.dds"); // opens file from d:\mygame\data\textures\hello.dds
+ * @endcode
+ * @param directory directory on the disk to add to root directories of virtual-filesystem
+ * @ingroup fileio
+ */
+CORE_API void io_addvdir(const char* directory, bool_t monitor);
+
+/**
+ * Clears virtual directories 
+ * @ingroup fileio
+ */
+CORE_API void io_clearvdirs();
+
+/**
+ * Add/clear pak files to the virtual-filesystems\n
+ * Files inside pak-file behaves like a virtual-disk, and are referenced same as virtual-directories\n
+ * **Note** handling of opening and closing the pak-files must be managed by user
+ * @see pak_file
+ * @see io_addvdir
+ * @ingroup fileio
+ */
+CORE_API void io_addpak(struct pak_file* pak);
+
+/**
+ * Clear pak files list in the virtual filesystem
+ * @ingroup fileio
+ */
+CORE_API void io_clearpaks();
+
+ /**
+  * Create a file in memory 
+  * @param alloc memory allocator for internal file data
+  * @param name name alias (or filepath) that will be binded to the file
+  * @return valid file handle or FILE_NULL if failed
+  * @ingroup fileio
+  */
+CORE_API file_t io_file_createmem(struct allocator* alloc, const char* name, uint32 mem_id);
+
+/**
+ * open a file from disk into memory
+ * @param filepath filepath to the file on disk (must exist), filepath will first check -
+ * virtual-filesystems for valid path unless ignore_vfs option is set
+ * @param ignore_vfs if true, virtual-filesystems will be ignored and file will be loaded directly
+ * @return valid file handle or FILE_NULL if failed
+ * @ingroup fileio
+  */
+CORE_API file_t io_file_openmem(struct allocator* alloc, const char* filepath, 
+                                bool_t ignore_vfs, uint32 mem_id);
+/**
+ * Attach a memory buffer to the file for reading, attached buffer should not be - 
+ * managed (deallocated) by caller anymore
+ * @param alloc allocator that used to create the buffer
+ * @param buffer buffer that we want to attach
+ * @param name name alias (or filepath) that will be binded to the file
+ * @return valid file handle or FILE_NULL if failed
+ * @ingroup fileio
+  */
+CORE_API file_t io_file_attachmem(struct allocator* alloc, void* buffer, 
+                                  size_t size, const char* name, uint32 mem_id);
+
+/**
+ * Detach buffer from memory file, after file is detached\n
+ * note that file is not closed after detaching it's memory, user must close it after detach
+ * @param outsize output size of the buffer
+ * @param palloc pointer (out) to the allocator that used to create file buffer
+ * @return file data buffer, caller should manage freeing the buffer
+ * @ingroup fileio
+ */
+CORE_API void* io_file_detachmem(file_t f, size_t* outsize, struct allocator** palloc);
+
+/**
+ * Create a file on disk 
+ * @param ignore_vfs sets if we have to ignore opening from virtual-filesystems
+ * @return valid file handle or FILE_NULL if failed
+ * @ingroup fileio
+ */
+CORE_API file_t io_file_createdisk(const char* filepath);
+
+/**
+ * Opens a file from disk (must exist), filepath will first check virtual-filesystems for valid -
+ * path unless ignore_vfs option is set
+ * @param ignore_vfs if true, virtual-filesystems will be ignored and file will be loaded directly
+ * @return valid file handle or FILE_NULL if failed
+ * @ingroup fileio
+ */
+CORE_API file_t io_file_opendisk(const char* filepath, bool_t ignore_vfs);
+
+/**
+ * Close an opened file
+ * @ingroup fileio
+ */
+CORE_API void io_file_close(file_t f);
+
+/**
+ * Seeks in the file 
+ * @param seek defines where should seeking begin (see seek_mode)
+ * @param offset offset from the seek point to move in the file, can be positive/negative
+ * @ingroup fileio
+ */
+CORE_API void io_file_seek(file_t f, enum seek_mode seek, int32 offset);
+
+/**
+ * Reads data from file
+ * @param buffer output buffer, buffer should have enough size of (item_size*items_cnt)
+ * @param item_size size of each item in bytes
+ * @param items_cnt number of items to read
+ * @return number of items that is read, =0 if error occurs
+ * @ingroup fileio
+ */
+CORE_API size_t io_file_read(file_t f, void* buffer, size_t item_size, size_t items_cnt);
+
+/**
+ * Writes data to file
+ * @param buffer input buffer, buffer should have enough size of (item_size*items_cnt)
+ * @param item_size size of each item in bytes
+ * @param items_cnt number of items to read
+ * @return number of items that is written to file, =0 if error occurs
+ * @ingroup fileio
+*/
+CORE_API size_t io_file_write(file_t f, const void* buffer, size_t item_size, size_t items_cnt);
+
+/**
+ * @return File size in bytes
+ * @ingroup fileio
+ */
+CORE_API size_t io_file_getsize(file_t f);
+
+/**
+ * @return Current position offset in the file (in bytes)
+ * @ingroup fileio
+ */
+CORE_API size_t io_file_getpos(file_t f);
+
+/**
+ * Returns file-path, the one that is called with io_file_openXXX functions
+ * @ingroup fileio
+ */
+CORE_API const char* io_file_getpath(file_t f);
+
+/**
+ * Checks if file is already opened
+ * @ingroup fileio
+ */
+CORE_API bool_t io_file_isopen(file_t f);
+
+/**
+ * Get opened file type
+ * @see file_type 
+ * @ingroup fileio
+ */
+CORE_API enum file_type io_file_gettype(file_t f);
+/**
+ * get opened file mode (read/write)
+ * @see FILE_MODE_READ  
+ * @ingroup fileio
+ */
+CORE_API enum file_mode io_file_getmode(file_t f);
+
+/**
+ * @ingroup fileio
+ */
+CORE_API void io_mon_reg(const char* filepath, pfn_filechange_callback fn, reshandle_t hdl, 
+    uptr_t param1, uptr_t param2);
+
+/**
+ * @ingroup fileio
+ */
+CORE_API void io_mon_unreg(const char* filepath);
+
+/**
+ * @ingroup fileio
+ */
+CORE_API void io_mon_update();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FILEMGR_H__*/

include/core/freelist-alloc.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+#ifndef __FREELIST_ALLOC_H__
+#define __FREELIST_ALLOC_H__
+
+#include "types.h"
+#include "allocator.h"
+#include "linked-list.h"
+#include "core-api.h"
+
+/**
+ * freelist allocator: variable-sized small block memory allocator\n
+ * more that 8k memory blocks will be allocated from heap
+ * @ingroup alloc
+ */
+struct freelist_alloc
+{
+    uint8*              buffer;
+    size_t              size;
+    size_t              alloc_size;
+    struct linked_list* free_chunks;
+    struct linked_list* alloc_chunks;
+    struct allocator*   alloc;
+};
+
+#ifdef __cplusplus
+extern "C"  {
+#endif
+
+/**
+ * freelist create/destroy 
+ * @param alloc allocator for internal freelist memory
+ * @param size size (in bytes) for freelist buffer
+ * @see mem_freelist_destroy    @ingroup alloc
+ */
+CORE_API result_t mem_freelist_create(struct allocator* alloc, 
+                                      struct freelist_alloc* freelist,
+                                      size_t size, uint32 mem_id);
+/**
+ * destroy freelist
+ * @ingroup alloc
+ */
+CORE_API void mem_freelist_destroy(struct freelist_alloc* freelist);
+
+/**
+ * allocate memory from freelist
+ * @param size size (in bytes) of requested memory, if requested size is more than 8k -
+ * see (freelist-alloc.c), memory will be allocated from heap instead of freelist
+ * @return allocated memory block   @ingroup alloc
+ */
+CORE_API void* mem_freelist_alloc(struct freelist_alloc* freelist, size_t size, uint32 mem_id);
+/**
+ * @ingroup alloc
+ */
+CORE_API void* mem_freelist_alignedalloc(struct freelist_alloc* freelist, size_t size, 
+                                         uint8 alignment, uint32 mem_id);
+/**
+ * @ingroup alloc
+ */
+CORE_API void mem_freelist_free(struct freelist_alloc* freelist, void* ptr);
+/**
+ * @ingroup alloc
+ */
+CORE_API void mem_freelist_alignedfree(struct freelist_alloc* freelist, void* ptr);
+/**
+ * get freelist memory leaks
+ * @param pptrs array of pointers to the leaks, if =NULL function only returns number of leaks
+ * @return number of leaks
+ * @ingroup alloc
+ */
+CORE_API uint32 mem_freelist_getleaks(struct freelist_alloc* freelist, void** pptrs);
+
+/**
+ * get size of the allocated memory from freelist
+ */
+CORE_API size_t mem_freelist_getsize(struct freelist_alloc* freelist, void* ptr);
+
+/**
+ * bind freelist-alloc to generic allocator 
+ * @ingroup alloc
+ */
+CORE_API void mem_freelist_bindalloc(struct freelist_alloc* freelist, struct allocator* alloc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

include/core/hash-table.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+#ifndef __HASHTABLE_H__
+#define __HASHTABLE_H__
+
+#include "types.h"
+#include "linked-list.h"
+#include "array.h"
+#include "allocator.h"
+#include "core-api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup htable Hash-table: containers
+ */
+
+/**
+ * common string hashing helper function
+ * @ingroup htable
+ */
+CORE_API uint32 hashtable_str(const char* str);
+ 
+ /**
+ * hash table item, used in open/fixed hash tables
+ * @ingroup htable
+ */
+struct hashtable_item
+{
+    uint32 hash;   /**< hash */
+    uptr_t value;  /**< saved user value */
+};
+
+ /**
+ * hash table item, used in chained hash tables
+ * @ingroup htable
+ */
+struct hashtable_item_chained
+{
+    uint32 hash;   /**< hash */
+    uptr_t value;  /**< saved user value */
+    struct linked_list node;    /* for chaining hash collisions */
+};
+
+/**
+ * chained hash table
+ * cjaomed hash tables can hold unlimited number of items\n
+ * but needs dynamic allocator and may turn into a simple linked-list in worst case
+ * @ingroup htable
+ */
+struct hashtable_chained
+{
+    struct allocator* item_alloc;
+    struct allocator* alloc;
+    uint32 mem_id;
+    struct linked_list** pslots;
+    uint32 slots_cnt;
+    uint32 items_cnt;
+};
+
+/* chained hash table functions 
+ **
+ * create: creates hash table data
+ * @param alloc allocator for hash table main buffers which is created immediately after call
+ * @param item_alloc hash item allocator (hashtable_item_chained), recommended allocator is mem-pool
+ * @param slots_cnt number of slots in hash table, bigger number creates faster hash table
+ * @ingroup htable
+ */
+CORE_API result_t hashtable_chained_create(struct allocator* alloc, struct allocator* item_alloc,
+                                       struct hashtable_chained* table,
+                                       uint32 slots_cnt, uint32 mem_id);
+
+/**
+ * destroy hash table 
+ * @ingroup htable
+ */
+CORE_API void hashtable_chained_destroy(struct hashtable_chained* table);
+/**
+ * checks if hash table is empty 
+ * @ingroup htable
+ */
+CORE_API bool_t hashtable_chained_isempty(struct hashtable_chained* table);
+/**
+ * add item to hash table, constains key/value pair
+ * @param hash_key hash key, can be created with hash functions
+ * @param value 64bit value, can be casted to pointer
+ * @see hash
+ * @ingroup htable
+ */
+CORE_API result_t hashtable_chained_add(struct hashtable_chained* table, uint32 hash_key, 
+    uint64 value);
+/**
+ * removes hash item from the hash table 
+ * @ingroup htable
+ */
+CORE_API void hashtable_chained_remove(struct hashtable_chained* table, 
+    struct hashtable_item_chained* item);
+ /**
+  * finds hash table by key
+  * @return found item, NULL if not found
+  * @see hashtable_item_chained
+  * @ingroup htable
+  */
+CORE_API struct hashtable_item_chained* hashtable_chained_find(
+    const struct hashtable_chained* table, 
+    uint32 hash_key);
+/**
+ * clears hash table items 
+ * @ingroup htable
+ */
+CORE_API void hashtable_chained_clear(struct hashtable_chained* table);
+
+/**
+ * closed hash table\n
+ * closed tables holds a limited amount of items, but does not need dynamic allocator\n
+ * 'prime number' maximum items are prefered : \n
+ * http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
+ * @ingroup htable
+ */
+struct hashtable_fixed
+{
+    struct allocator* alloc;
+    struct hashtable_item* slots;
+    uint32 slots_cnt;
+    uint32 items_cnt;
+};
+
+/* closed hash table functions 
+ **
+ * create: creates hash table data
+ * @param alloc allocator for hash table main buffers which is created immediately after call
+ * @param slots_cnt number of slots in hash table, prime numbers are pefered for optimized hash-table
+ * @ingroup htable
+ */
+CORE_API result_t hashtable_fixed_create(struct allocator* alloc,
+                                         struct hashtable_fixed* table,
+                                         uint32 slots_cnt, uint32 mem_id);
+
+/**
+ * destroy hash table 
+ * @ingroup htable
+ */
+CORE_API void hashtable_fixed_destroy(struct hashtable_fixed* table);
+/**
+ * checks if hash table is empty 
+ * @ingroup htable
+ */
+CORE_API bool_t hashtable_fixed_isempty(struct hashtable_fixed* table);
+/**
+ * add item to hash table, constains key/value pair
+ * @param hash_key hash key, can be created with hash functions
+ * @param value 64bit value, can be casted to pointer
+ * @see hash
+ * @ingroup htable
+ */
+CORE_API result_t hashtable_fixed_add(struct hashtable_fixed* table, 
+                                      uint32 hash_key, uint64 value);
+/**
+ * removes hash item from the hash table 
+ * @ingroup htable
+ */
+CORE_API void hashtable_fixed_remove(struct hashtable_fixed* table, struct hashtable_item* item);
+ /**
+  * finds hash table by key
+  * @return found item, NULL if not found
+  * @ingroup htable
+  */
+CORE_API struct hashtable_item* hashtable_fixed_find(const struct hashtable_fixed* table, 
+                                                      uint32 hash_key);
+/**
+ * clears hash table items 
+ * @ingroup htable
+ */
+CORE_API void hashtable_fixed_clear(struct hashtable_fixed* table);
+
+/** 
+ * open hash table : same as closed hash table, but grows itself upon extra item additions
+ */
+struct hashtable_open
+{
+    struct allocator* alloc;
+    struct hashtable_item* slots;
+    uint32 slots_cnt;
+    uint32 items_cnt;
+    uint32 slots_grow;
+    uint32 mem_id;
+};
+
+/* open hash table functions 
+ **
+ * create: creates hash table data
+ * @param alloc allocator for hash table main buffers which is created immediately after call
+ * @param slots_cnt number of slots in hash table, prime numbers are pefered for optimized hash-table
+ * @ingroup htable
+ */
+CORE_API result_t hashtable_open_create(struct allocator* alloc,
+                                        struct hashtable_open* table,
+                                        uint32 slots_cnt, uint32 grow_cnt, 
+                                        uint32 mem_id);
+
+/**
+ * destroy hash table 
+ * @ingroup htable
+ */
+CORE_API void hashtable_open_destroy(struct hashtable_open* table);
+/**
+ * checks if hash table is empty 
+ * @ingroup htable
+ */
+CORE_API bool_t hashtable_open_isempty(struct hashtable_open* table);
+/**
+ * add item to hash table, constains key/value pair
+ * @param hash_key hash key, can be created with hash functions
+ * @param value 64bit value, can be casted to pointer
+ * @see hash
+ * @ingroup htable
+ */
+CORE_API result_t hashtable_open_add(struct hashtable_open* table, 
+                                     uint32 hash_key, uint64 value);
+/**
+ * removes hash item from the hash table 
+ * @ingroup htable
+ */
+CORE_API void hashtable_open_remove(struct hashtable_open* table, struct hashtable_item* item);
+ /**
+  * finds hash table by key
+  * @return found item, NULL if not found
+  * @ingroup htable
+  */
+CORE_API struct hashtable_item* hashtable_open_find(const struct hashtable_open* table, 
+                                                      uint32 hash_key);
+/**
+ * clears hash table items 
+ * @ingroup htable
+ */
+CORE_API void hashtable_open_clear(struct hashtable_open* table);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __HASHTABLE_H__ */

include/core/hash.h

+/***********************************************************************************
+ * Copyright (c) 2012, Sepehr Taghdisian
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ *
+ ***********************************************************************************/
+
+/*******************************************************************
+*   Hashing Routines
+*   Murmur3 Hash: http://code.google.com/p/smhasher/
+*   Note: Dissed other hashes, because murmur seems to beat them all
+*   Seed parameter in murmur hash functions are for variation
+*   you should always provide fixed seed values to get same result
+********************************************************************/
+
+#ifndef __HASH_H__
+#define __HASH_H__
+
+#include "types.h"
+#include "core-api.h"
+
+/**
+ * @defgroup hash Hashing functions
+ */
+
+#ifdef __cplusplus
+extern "C"  {
+#endif
+
+#if defined(_X64_)
+typedef struct hash_s
+{
+    uint64  h[2];
+} hash_t;
+#else
+typedef struct hash_s
+{
+    uint32  h[4];
+} hash_t;
+#endif
+
+/**
+ * Incremental hash structure
+ * @see hash_murmurincr_begin @ingroup hash
+ */
+struct hash_incr
+{
+	uint32 hash;
+	uint32 tail;
+	uint32 cnt;
+	uint32 size;
+};
+
+/**
+ * Test for 128bit hash equality
+ * @ingroup hash
+ */
+INLINE bool_t hash_isequal(hash_t h1, hash_t h2);
+
+#if defined(_X64_)
+INLINE bool_t hash_isequal(hash_t h1, hash_t h2)
+{
+    return (h1.h[0] == h2.h[0] && h1.h[1] == h2.h[1]);
+}
+
+INLINE void hash_set(hash_t* dest, hash_t src)
+{
+	dest->h[0] = src.h[0];
+	dest->h[1] = src.h[1];
+}
+
+INLINE void hash_zero(hash_t* h)
+{
+	h->h[0] = 0;
+	h->h[1] = 0;
+}
+
+#else
+INLINE bool_t hash_isequal(hash_t h1, hash_t h2)
+{
+    return (h1.h[0] == h2.h[0] && h1.h[1] == h2.h[1] && h1.h[2] == h2.h[2] && h1.h[3] == h2.h[3]);
+}
+
+INLINE void hash_set(hash_t* dest, hash_t src)
+{
+	dest->h[0] = src.h[0];
+	dest->h[1] = src.h[1];
+	dest->h[2] = src.h[2];
+	dest->h[3] = src.h[3];
+}
+
+INLINE void hash_zero(hash_t* h)
+{
+	h->h[0] = 0;		h->h[1] = 0;
+	h->h[2] = 0;		h->h[3] = 0;
+}
+#endif
+
+
+/**
+ * murmur 32bit hash
+ * @param key buffer containing data to be hashed
+ * @param size_bytes size of buffer (bytes)
+ * @param seed random seed value (must be same between hashes in order to compare
+ * @return 32bit hash value
+ * @ingroup hash
+ */
+CORE_API uint32 hash_murmur32(const void* key, uint32 size_bytes, uint32 seed);
+
+/**
+ * murmur 128bit hash
+ * @param key buffer containing data to be hashed
+ * @param size_bytes size of buffer (bytes)
+ * @param seed random seed value (must be same between hashes in order to compare
+ * @return 128bit hash value
+ * @ingroup hash
+ */
+CORE_API hash_t hash_murmur128(const void* key, uint32 size_bytes, uint32 seed);
+
+/**
+ * hash 64bit value to 32bit
+ * @param n 32bit value to be hashed
+ * @return 32bit hash value