├── var └── waf ├── libdhcore.pro ├── src ├── wscript ├── test │ ├── wscript │ ├── dhcore-test.h │ ├── test-taskmgr.c │ ├── test.pro │ ├── test-heap.c │ ├── test-thread.c │ ├── test-json.c │ ├── test-hashtable.cpp │ ├── test-pool.c │ ├── test-freelist.c │ └── dhcore-test.c └── core │ ├── platform │ ├── osx │ │ ├── util-osx.c │ │ ├── timer-osx.c │ │ └── hwinfo-osx.c │ ├── win │ │ ├── timer-win.c │ │ └── util-win.c │ ├── linux │ │ ├── util-lnx.c │ │ ├── timer-lnx.c │ │ └── hwinfo-lnx.c │ ├── ios │ │ └── fileio-ios.m │ └── posix │ │ ├── crash-posix.c │ │ └── util-posix.c │ ├── numeric.c │ ├── util.c │ ├── wscript │ ├── hwinfo.c │ ├── core.c │ ├── static-vars.cpp │ ├── array.c │ ├── std-math.c │ ├── zip.c │ ├── timer.c │ ├── core.pro │ ├── variant.c │ ├── path.c │ └── errors.c ├── libdhcore.sublime-project ├── .gitignore ├── doc ├── footer.html └── header.html ├── xcode └── dhcore │ ├── dhcore_iosTests │ └── Info.plist │ └── dhcore.xcodeproj │ └── xcuserdata │ └── Sepul.xcuserdatad │ └── xcschemes │ ├── xcschememanagement.plist │ ├── dhcore.xcscheme │ └── dhcore_ios.xcscheme ├── include └── dhcore │ ├── win.h │ ├── crash.h │ ├── error-codes.h │ ├── pak-file-fmt.h │ ├── core-api.h │ ├── core.h │ ├── path.h │ ├── zip.h │ ├── hwinfo.h │ ├── variant.h │ ├── std-math.h │ ├── log.h │ ├── stack.h │ ├── queue.h │ ├── pool-alloc.h │ ├── err.h │ ├── pak-file.h │ ├── hash.h │ ├── str.h │ ├── timer.h │ ├── freelist-alloc.h │ ├── linked-list.h │ ├── util.h │ ├── commander.h │ ├── numeric.h │ └── mem-mgr.h ├── LICENSE └── vs2013 └── libdhcore └── libdhcore.sln /var/waf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/septag/libdhcore/HEAD/var/waf -------------------------------------------------------------------------------- /libdhcore.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | CONFIG += ordered 3 | 4 | SUBDIRS += \ 5 | src/core \ 6 | src/test 7 | -------------------------------------------------------------------------------- /src/wscript: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | def build(bld): 4 | bld.recurse('core') 5 | if bld.env.BUILD_TESTS: 6 | bld.recurse('test') 7 | -------------------------------------------------------------------------------- /libdhcore.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "follow_symlinks": true, 6 | "path": "src" 7 | }, 8 | { 9 | "follow_symlinks": true, 10 | "path": "include" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/test/wscript: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import os, glob, sys 4 | 5 | def build(bld): 6 | bld.program( 7 | source = bld.path.ant_glob('*.c*'), 8 | target = 'dhcore-test' + bld.env.SUFFIX, 9 | includes = ['../../include'], 10 | install_path = '${PREFIX}/bin', 11 | use = ['dhcore']) 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # External junk 2 | .DS_Store 3 | _ReSharper* 4 | *.opensdf 5 | *.sdf 6 | *.dir 7 | *.suo 8 | *.user 9 | Win32 10 | Debug 11 | Release 12 | build 13 | .tags 14 | .tags_sorted_by_file 15 | .lock-waf_linux_build 16 | .lock-waf_win32_build 17 | *.sublime-workspace 18 | *.lnk 19 | ipch 20 | __pycache__ 21 | *.pyc 22 | waf3* 23 | 24 | # Generated files 25 | docs/Doxyfile 26 | docs/html 27 | docs/warnings.txt 28 | var/waf-* 29 | 3rdparty/tmp 30 | 31 | # Compiled binaries 32 | *.so 33 | *.dylib 34 | *.dll 35 | *.a 36 | *.lib 37 | *.exe 38 | -------------------------------------------------------------------------------- /doc/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /xcode/dhcore/dhcore_iosTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | github.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /xcode/dhcore/dhcore.xcodeproj/xcuserdata/Sepul.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | dhcore.xcscheme 8 | 9 | orderHint 10 | 5 11 | 12 | dhcore_ios.xcscheme 13 | 14 | orderHint 15 | 12 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 14BB3CBD1A86910700D39646 21 | 22 | primary 23 | 24 | 25 | 14BB3CC71A86910700D39646 26 | 27 | primary 28 | 29 | 30 | 14BEA56119FBD76C0077ADE2 31 | 32 | primary 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /include/dhcore/win.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | /* precompiled header for win32 */ 17 | #ifndef __WIN_H__ 18 | #define __WIN_H__ 19 | 20 | #include "types.h" 21 | 22 | #if defined(_WIN_) 23 | 24 | #if !defined(WIN32_LEAN_AND_MEAN) 25 | #define WIN32_LEAN_AND_MEAN 26 | #endif 27 | 28 | #if !defined(VC_EXTRALEAN) 29 | #define VC_EXTRALEAN 30 | #endif 31 | 32 | #include 33 | 34 | #include 35 | #endif 36 | 37 | 38 | #endif /* __WIN_H__ */ 39 | -------------------------------------------------------------------------------- /src/core/platform/osx/util-osx.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2013, Davide Bacchet 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/util.h" 17 | 18 | #if defined(_APPLE_) 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "dhcore/str.h" 25 | #include "dhcore/path.h" 26 | 27 | char* util_getexedir(char* outpath) 28 | { 29 | uint32_t tmpsize = DH_PATH_MAX; 30 | _NSGetExecutablePath(outpath, &tmpsize); 31 | return path_getdir(outpath, outpath); 32 | } 33 | 34 | #endif /* _OSX_ */ 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Sepehr Taghdisian 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | - 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. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | -------------------------------------------------------------------------------- /include/dhcore/crash.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2013, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef __CRASH_H__ 17 | #define __CRASH_H__ 18 | 19 | #include "types.h" 20 | #include "core-api.h" 21 | 22 | /** 23 | * Crash handler callback function 24 | * @ingroup core 25 | */ 26 | typedef void (*pfn_crash_handler)(); 27 | 28 | /* */ 29 | result_t crash_init(); 30 | 31 | /** 32 | * Sets crash handler callback function, so when application crashes, the callback is called. 33 | * @ingroup core 34 | */ 35 | CORE_API void crash_set_handler(pfn_crash_handler crash_fn); 36 | 37 | #endif /* __CRASH_H__ */ -------------------------------------------------------------------------------- /src/core/platform/osx/timer-osx.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2013, Davide Bacchet 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/timer.h" 17 | 18 | #if defined(_APPLE_) 19 | 20 | #include 21 | 22 | static struct mach_timebase_info g_freq; 23 | 24 | void timer_queryfreq() 25 | { 26 | mach_timebase_info(&g_freq); 27 | } 28 | 29 | uint64 timer_querytick() 30 | { 31 | return mach_absolute_time(); 32 | } 33 | 34 | fl64 timer_calctm(uint64 tick1, uint64 tick2) 35 | { 36 | uint64 delta_tick = tick2 - tick1; 37 | uint64 utm = delta_tick*g_freq.numer/g_freq.denom; 38 | return (double)utm/1e9; 39 | } 40 | 41 | #endif /* _OSX_ */ 42 | -------------------------------------------------------------------------------- /src/core/platform/win/timer-win.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/timer.h" 17 | 18 | #if defined(_WIN_) 19 | 20 | #include "dhcore/win.h" 21 | 22 | static LARGE_INTEGER g_freq; 23 | 24 | void timer_queryfreq() 25 | { 26 | QueryPerformanceFrequency(&g_freq); 27 | } 28 | 29 | uint64 timer_querytick() 30 | { 31 | LARGE_INTEGER tick; 32 | QueryPerformanceCounter(&tick); 33 | return (uint64)tick.QuadPart; 34 | } 35 | 36 | fl64 timer_calctm(uint64 tick1, uint64 tick2) 37 | { 38 | uint64 delta_tick = tick2 - tick1; 39 | return (double)delta_tick/(double)g_freq.QuadPart; 40 | } 41 | 42 | #endif /* _WIN_ */ 43 | -------------------------------------------------------------------------------- /src/core/platform/linux/util-lnx.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/util.h" 17 | 18 | #if defined(_LINUX_) 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "dhcore/path.h" 29 | 30 | char* util_getexedir(char* outpath) 31 | { 32 | char tmp[32]; 33 | sprintf(tmp, "/proc/%d/exe", getpid()); 34 | size_t bytes = readlink(tmp, outpath, DH_PATH_MAX-1); 35 | outpath[bytes] = 0; 36 | return path_getdir(outpath, outpath); 37 | } 38 | 39 | 40 | #endif /* _LINUX_ */ 41 | -------------------------------------------------------------------------------- /src/test/dhcore-test.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef __DHCORE_TEST_H__ 17 | #define __DHCORE_TEST_H__ 18 | 19 | #include "dhcore/numeric.h" 20 | #include 21 | 22 | void test_json(); 23 | void test_heap(); 24 | void test_freelist(); 25 | void test_mempool(); 26 | void test_thread(); 27 | void test_efsw(); 28 | void test_taskmgr(); 29 | _EXTERN_ void test_hashtable(); 30 | 31 | INLINE void fill_buffer(void* buffer, size_t size) 32 | { 33 | uint int_cnt = (uint)(size/sizeof(int)); 34 | int* ibuf = (int*)buffer; 35 | 36 | for (uint i = 0; i < int_cnt; i++) { 37 | ibuf[i] = rand_geti(1, 100); 38 | } 39 | } 40 | 41 | 42 | #endif /* __DHCORE_TEST_H__ */ 43 | -------------------------------------------------------------------------------- /src/test/test-taskmgr.c: -------------------------------------------------------------------------------- 1 | #include "dhcore/core.h" 2 | #include "dhcore/task-mgr.h" 3 | #include "dhcore/hwinfo.h" 4 | 5 | void task_run(void* params, void* result, uint thread_id, uint job_id, uint worker_idx) 6 | { 7 | printf("Task-> ID:%d, Thread:%d, Worker:%d\n", job_id, thread_id, worker_idx); 8 | uint counter = 0; 9 | while (counter != 1000000000) 10 | counter ++; 11 | } 12 | 13 | void test_taskmgr() 14 | { 15 | log_print(LOG_TEXT, "Initializing task-mgr ..."); 16 | 17 | struct hwinfo info; 18 | hw_getinfo(&info, HWINFO_CPU); 19 | 20 | //tsk_zero(); 21 | log_printf(LOG_TEXT, "Intiating %d threads ...", info.cpu_core_cnt - 1); 22 | tsk_initmgr(maxui(info.cpu_core_cnt - 1, 1), 0, 0, 0); 23 | 24 | log_print(LOG_TEXT, "Dispatching tasks #1 ..."); 25 | uint task_id = tsk_dispatch(task_run, TSK_CONTEXT_ALL_NO_MAIN, TSK_THREADS_ALL, NULL, NULL); 26 | tsk_wait(task_id); 27 | log_print(LOG_TEXT, "tasks #1 finished"); 28 | util_sleep(1000); 29 | log_print(LOG_TEXT, "Dispatching tasks #2 ..."); 30 | uint task_id2 = tsk_dispatch(task_run, TSK_CONTEXT_ALL_NO_MAIN, TSK_THREADS_ALL, NULL, NULL); 31 | tsk_wait(task_id2); 32 | log_print(LOG_TEXT, "tasks #2 finished"); 33 | 34 | tsk_destroy(task_id); 35 | tsk_destroy(task_id2); 36 | 37 | log_print(LOG_TEXT, "Finished, Releasing task-mgr..."); 38 | tsk_releasemgr(); 39 | log_print(LOG_TEXT, "done."); 40 | } 41 | -------------------------------------------------------------------------------- /src/core/platform/linux/timer-lnx.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/timer.h" 17 | 18 | #if defined(_LINUX_) 19 | 20 | #include 21 | 22 | #define BILLION 1000000000L 23 | 24 | static struct timespec g_freq; 25 | 26 | void timer_queryfreq() 27 | { 28 | clock_getres(CLOCK_MONOTONIC, &g_freq); 29 | } 30 | 31 | uint64 timer_querytick() 32 | { 33 | struct timespec t; 34 | clock_gettime(CLOCK_MONOTONIC, &t); 35 | return (uint64)t.tv_sec*BILLION + (uint64)t.tv_nsec; 36 | } 37 | 38 | fl64 timer_calctm(uint64 tick1, uint64 tick2) 39 | { 40 | uint64 delta_tick = tick2 - tick1; 41 | uint64 utm = delta_tick/g_freq.tv_nsec; 42 | return (double)utm/1e9; 43 | } 44 | 45 | #endif /* _LINUX_ */ 46 | -------------------------------------------------------------------------------- /src/core/numeric.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include 17 | #include 18 | #include "dhcore/numeric.h" 19 | #include "dhcore/err.h" 20 | 21 | /*************************************************************************************************/ 22 | void rand_seed() 23 | { 24 | srand((unsigned int)time(NULL)); 25 | } 26 | 27 | int rand_flipcoin(uint prob) 28 | { 29 | return ((uint)rand_geti(0, 100) <= prob); 30 | } 31 | 32 | int rand_geti(int min, int max) 33 | { 34 | int r = rand(); 35 | return ((r % (max-min+1)) + min); 36 | } 37 | 38 | float rand_getf(float min, float max) 39 | { 40 | fl64 r = ((fl64)rand())/RAND_MAX; /* [0, 1] */ 41 | return (float)((r * (max-min)) + min); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/test/test.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | CONFIG += console 3 | CONFIG -= app_bundle 4 | CONFIG -= qt 5 | CONFIG += warn_off 6 | 7 | INCLUDEPATH = ../../include 8 | 9 | DEFINES += _VERSION_=\\\"1.0\\\" 10 | 11 | linux-g++|linux-clang|macx-clang { 12 | QMAKE_CFLAGS += \ 13 | -std=gnu99 \ 14 | -msse -msse2 \ 15 | -ffast-math 16 | QMAKE_CXXFLAGS += \ 17 | -msse -msse2 \ 18 | -ffast-math \ 19 | -std=c++11 20 | LIBS *= -lpthread -lm 21 | } 22 | 23 | win32-msvc2013 | win32-msvc2012 | win32-msvc2010 { 24 | QMAKE_CFLAGS += /TP 25 | 26 | CONFIG(debug, debug|release) { 27 | DEFINES += _DEBUG 28 | } 29 | 30 | DEFINES += _CRT_SECURE_NO_WARNINGS _WINDOWS _WINDLL _MBCS 31 | DEFINES -= UNICODE 32 | 33 | LIBS += -lws2_32 -lShlwapi -luser32 -lgdi32 -lkernel32 -lAdvapi32 -lShell32 34 | } 35 | 36 | SOURCES += \ 37 | dhcore-test.c \ 38 | test-freelist.c \ 39 | test-heap.c \ 40 | test-json.c \ 41 | test-pool.c \ 42 | test-taskmgr.c \ 43 | test-thread.c \ 44 | test-hashtable.cpp 45 | 46 | HEADERS += \ 47 | dhcore-test.h 48 | 49 | # dhcore lib 50 | win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../core/release/ -ldhcore 51 | else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../core/debug/ -ldhcore 52 | else:unix:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../core/ -ldhcore 53 | else:unix:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../core/ -ldhcore-dbg 54 | 55 | DEPENDPATH += $$PWD/../core 56 | -------------------------------------------------------------------------------- /include/dhcore/error-codes.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef __ERRORCODES_H__ 17 | #define __ERRORCODES_H__ 18 | 19 | 20 | /* error codes */ 21 | #define RET_ABORT 2 22 | #define RET_OK 1 23 | #define RET_FAIL 0 24 | #define RET_OUTOFMEMORY -1 25 | #define RET_WARNING -2 26 | #define RET_INVALIDARG -3 27 | #define RET_FILE_ERROR -4 28 | #define RET_NOT_IMPL -5 29 | #define RET_NOT_SUPPORTED -6 30 | #define RET_INVALIDCALL -7 31 | 32 | /** 33 | * Macro to check if @e result_t type is an error 34 | * @ingroup err 35 | */ 36 | #define IS_FAIL(r) ((r) <= 0) 37 | 38 | /** 39 | * Macro to check if @e result_t type is success 40 | * @ingroup err 41 | */ 42 | #define IS_OK(r) ((r) > 0) 43 | 44 | #endif /* __ERRORCODES_H__ */ 45 | -------------------------------------------------------------------------------- /src/test/test-heap.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore-test.h" 17 | #include "dhcore/core.h" 18 | #include "dhcore/json.h" 19 | #include "dhcore/timer.h" 20 | 21 | void test_heap() 22 | { 23 | const uint item_cnt = 1000; 24 | void* ptrs[item_cnt]; 25 | 26 | uint64 t1 = timer_querytick(); 27 | 28 | log_printf(LOG_TEXT, "allocating %d items from heap...", item_cnt); 29 | for (uint i = 0; i < item_cnt; i++) { 30 | ptrs[i] = A_ALLOC(mem_heap(), rand_geti(16, 1024), 0); 31 | ASSERT(ptrs[i]); 32 | } 33 | 34 | for (uint i = 0; i < item_cnt; i++) { 35 | if (rand_flipcoin(20)) { 36 | A_FREE(mem_heap(), ptrs[i]); 37 | } 38 | } 39 | 40 | log_printf(LOG_TEXT, "took %f ms.", 41 | timer_calctm(t1, timer_querytick())*1000.0f); 42 | } 43 | -------------------------------------------------------------------------------- /include/dhcore/pak-file-fmt.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | 17 | #ifndef __PAKFILEFMT_H__ 18 | #define __PAKFILEFMT_H__ 19 | 20 | #include "types.h" 21 | #include "hash.h" 22 | 23 | #define PAK_SIGN "HPAK" 24 | 25 | #pragma pack(push, 1) 26 | struct pak_header 27 | { 28 | char sig[5]; 29 | uint version; 30 | uint64 items_offset; 31 | uint64 items_cnt; 32 | uint compress_mode; 33 | }; 34 | 35 | /* pak file item, for each file in the pak I store one of these */ 36 | struct pak_item 37 | { 38 | char filepath[DH_PATH_MAX]; /* filepath (alias) of the file for referencing */ 39 | uint64 offset; /* offset in the pak (in bytes) */ 40 | uint size; /* actual compressed size (in bytes) */ 41 | uint unzip_size; /* unzipped size (in bytes) */ 42 | hash_t hash; /* hash for data validity */ 43 | }; 44 | #pragma pack(pop) 45 | 46 | #endif /*__PAKFILEFMT_H__*/ 47 | -------------------------------------------------------------------------------- /src/test/test-thread.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/core.h" 17 | #include "dhcore/mt.h" 18 | #include 19 | 20 | #if defined(_WIN_) 21 | #define sleep(x) Sleep(x*1000) 22 | #else 23 | #include 24 | #endif 25 | 26 | result_t kernel(mt_thread param) 27 | { 28 | printf("kernel...\n"); 29 | sleep(1); 30 | return RET_OK; 31 | } 32 | 33 | result_t init(mt_thread param) 34 | { 35 | printf("thread init\n"); 36 | return RET_OK; 37 | } 38 | 39 | void release(mt_thread param) 40 | { 41 | printf("thread release\n"); 42 | } 43 | 44 | void test_thread() 45 | { 46 | log_print(LOG_TEXT, "thread test ..."); 47 | mt_thread t = mt_thread_create(kernel, init, release, MT_THREAD_NORMAL, 0, 0, NULL, NULL); 48 | log_print(LOG_TEXT, "waiting for thread work ..."); 49 | sleep(5); 50 | log_print(LOG_TEXT, "destroying thread"); 51 | mt_thread_destroy(t); 52 | log_print(LOG_TEXT, "thread destroyed"); 53 | } 54 | -------------------------------------------------------------------------------- /src/test/test-json.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore-test.h" 17 | #include "dhcore/core.h" 18 | #include "dhcore/json.h" 19 | #include "dhcore/file-io.h" 20 | 21 | void test_json() 22 | { 23 | file_t f = fio_opendisk("data.json", TRUE); 24 | if (f != NULL) { 25 | json_t j = json_parsefilef(f, mem_heap()); 26 | if (j != NULL) { 27 | log_printf(LOG_TEXT, "name = %s", json_gets(json_getitem(j, "name"))); 28 | json_t jprops = json_getitem(j, "props"); 29 | log_printf(LOG_TEXT, "ass = %s", json_gets(json_getitem(jprops, "ass"))); 30 | log_printf(LOG_TEXT, "age = %d", json_geti(json_getitem(jprops, "age"))); 31 | log_printf(LOG_TEXT, "skin = %s", json_gets(json_getitem(jprops, "skin"))); 32 | log_printf(LOG_TEXT, "married = %d", json_getb(json_getitem(jprops, "married"))); 33 | } else { 34 | err_sendtolog(FALSE); 35 | } 36 | 37 | fio_close(f); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/test-hashtable.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore-test.h" 17 | #include "dhcore/core.h" 18 | #include "dhcore/hash-table.h" 19 | #include "dhcore/color.h" 20 | #include "dhcore/std-math.h" 21 | #include "dhcore/timer.h" 22 | #include "dhcore/numeric.h" 23 | 24 | using namespace dh; 25 | 26 | void test_hashtable() 27 | { 28 | const int item_cnt = 100000; 29 | ProfileTimer tm; 30 | HashtableFixed htable; 31 | 32 | int *keys = (int*)ALLOC(sizeof(int)*item_cnt, 0); 33 | ASSERT(keys); 34 | for (int i = 0; i < item_cnt; i++) 35 | keys[i] = rand_geti(0, 1000000); 36 | 37 | htable.create(item_cnt); 38 | 39 | printf("adding %d items to fixed hashtable ...\n", item_cnt); 40 | tm.begin(); 41 | for (int i = 0; i < item_cnt; i++) 42 | htable.add(keys[i], i); 43 | printf("time: %f\n", tm.end()); 44 | 45 | printf("searching %d items ...\n", item_cnt); 46 | tm.begin(); 47 | for (int i = 0; i < item_cnt; i++) 48 | htable.value(keys[i]); 49 | printf("time: %f\n", tm.end()); 50 | 51 | htable.destroy(); 52 | FREE(keys); 53 | } 54 | -------------------------------------------------------------------------------- /src/core/util.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2013, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/util.h" 17 | 18 | #include 19 | 20 | #include "dhcore/err.h" 21 | #include "dhcore/mem-mgr.h" 22 | 23 | /*************************************************************************************************/ 24 | char* util_readtextfile(const char* txt_filepath, struct allocator* alloc) 25 | { 26 | FILE* f = fopen(txt_filepath, "rb"); 27 | if (f == NULL) { 28 | err_printf(__FILE__, __LINE__, "could not open text file '%s'", txt_filepath); 29 | return NULL; 30 | } 31 | 32 | fseek(f, 0, SEEK_END); 33 | size_t s = ftell(f); 34 | if (s == 0) { 35 | err_printf(__FILE__, __LINE__, "text file '%s' is empty", txt_filepath); 36 | fclose(f); 37 | return NULL; 38 | } 39 | fseek(f, 0, SEEK_SET); 40 | 41 | char* buffer = (char*)A_ALLOC(alloc, s + 1, 0); 42 | if (buffer == NULL) { 43 | fclose(f); 44 | err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY); 45 | return NULL; 46 | } 47 | 48 | fread(buffer, s, 1, f); 49 | buffer[s] = 0; 50 | fclose(f); 51 | return buffer; 52 | } 53 | -------------------------------------------------------------------------------- /include/dhcore/core-api.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | 17 | #ifndef __COREAPI_H__ 18 | #define __COREAPI_H__ 19 | 20 | #include "types.h" 21 | 22 | #ifndef _CORE_STATICLIB_ 23 | #if defined(_CORE_EXPORT_) 24 | #if defined(_MSVC_) 25 | #define CORE_API _EXTERN_EXPORT_ __declspec(dllexport) 26 | #define CORE_CPP_API __declspec(dllexport) 27 | #elif defined(_GNUC_) 28 | #define CORE_API _EXTERN_EXPORT_ __attribute__((visibility("default"))) 29 | #define CORE_CPP_API __attribute__((visibility("default"))) 30 | #endif 31 | #else 32 | #if defined(_MSVC_) 33 | #define CORE_API _EXTERN_EXPORT_ __declspec(dllimport) 34 | #define CORE_CPP_API __declspec(dllimport) 35 | #elif defined(_GNUC_) 36 | #define CORE_API _EXTERN_EXPORT_ __attribute__((visibility("default"))) 37 | #define CORE_CPP_API __attribute__((visibility("default"))) 38 | #endif 39 | #endif /* defined(_CORE_EXPORT) */ 40 | #else 41 | #define CORE_API _EXTERN_EXPORT_ 42 | #define CORE_CPP_API 43 | #endif 44 | 45 | #if defined(SWIG) 46 | #define CORE_API 47 | #define CORE_CPP_API 48 | #endif 49 | 50 | #endif /* __COREAPI_H__*/ 51 | -------------------------------------------------------------------------------- /src/test/test-pool.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/core.h" 17 | #include "dhcore/pool-alloc.h" 18 | #include "dhcore/timer.h" 19 | 20 | void test_mempool() 21 | { 22 | const uint item_cnt = 1000; 23 | void* ptrs[item_cnt]; 24 | struct pool_alloc pool; 25 | struct allocator alloc; 26 | 27 | uint s = rand_geti(64, 1024); 28 | mem_pool_create(mem_heap(), &pool, s, 100, 0); 29 | mem_pool_bindalloc(&pool, &alloc); 30 | 31 | uint64 t1 = timer_querytick(); 32 | 33 | log_printf(LOG_TEXT, "allocating %d items from pool...", item_cnt); 34 | for (uint i = 0; i < item_cnt; i++) { 35 | ptrs[i] = A_ALLOC(&alloc, s, 0); 36 | ASSERT(ptrs[i]); 37 | } 38 | 39 | for (uint i = 0; i < item_cnt; i++) { 40 | if (rand_flipcoin(50)) { 41 | A_FREE(&alloc, ptrs[i]); 42 | ptrs[i] = NULL; 43 | } 44 | } 45 | 46 | /* report leaks */ 47 | uint leaks_cnt = mem_pool_getleaks(&pool); 48 | if (leaks_cnt > 0) { 49 | log_printf(LOG_TEXT, "%d leaks found", leaks_cnt); 50 | } 51 | 52 | log_print(LOG_TEXT, "done."); 53 | log_printf(LOG_TEXT, "took %f ms.", timer_calctm(t1, timer_querytick())*1000.0f); 54 | 55 | mem_pool_destroy(&pool); 56 | } 57 | -------------------------------------------------------------------------------- /doc/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | $projectname: $title 9 | $title 10 | 11 | 12 | 13 | $treeview 14 | $search 15 | $mathjax 16 | 17 | $extrastylesheet 18 | 19 | 20 |
21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
32 |
$projectname 33 |  $projectnumber 34 |
35 |
$projectbrief
36 |
41 |
$projectbrief
42 |
$searchbox
53 |
54 | 55 | 56 | -------------------------------------------------------------------------------- /vs2013/libdhcore/libdhcore.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30501.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdhcore", "libdhcore.vcxproj", "{A774897A-ACBB-4F95-A098-15A84FC8995B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug_Static|Win32 = Debug_Static|Win32 11 | Debug_Static|x64 = Debug_Static|x64 12 | Debug|Win32 = Debug|Win32 13 | Debug|x64 = Debug|x64 14 | Release_Static|Win32 = Release_Static|Win32 15 | Release_Static|x64 = Release_Static|x64 16 | Release|Win32 = Release|Win32 17 | Release|x64 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Debug_Static|Win32.ActiveCfg = Debug_Static|Win32 21 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Debug_Static|Win32.Build.0 = Debug_Static|Win32 22 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Debug_Static|x64.ActiveCfg = Debug_Static|x64 23 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Debug_Static|x64.Build.0 = Debug_Static|x64 24 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Debug|Win32.Build.0 = Debug|Win32 26 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Debug|x64.ActiveCfg = Debug|x64 27 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Debug|x64.Build.0 = Debug|x64 28 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Release_Static|Win32.ActiveCfg = Release_Static|Win32 29 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Release_Static|Win32.Build.0 = Release_Static|Win32 30 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Release_Static|x64.ActiveCfg = Release_Static|x64 31 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Release_Static|x64.Build.0 = Release_Static|x64 32 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Release|Win32.ActiveCfg = Release|Win32 33 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Release|Win32.Build.0 = Release|Win32 34 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Release|x64.ActiveCfg = Release|x64 35 | {A774897A-ACBB-4F95-A098-15A84FC8995B}.Release|x64.Build.0 = Release|x64 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /src/core/platform/ios/fileio-ios.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2015, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #import 17 | #include "dhcore/types.h" 18 | #include "dhcore/path.h" 19 | #include "dhcore/str.h" 20 | 21 | NSMutableArray *g_bundles = nil; 22 | 23 | int fio_ios_add_bundle(const char *bundle_name) 24 | { 25 | NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:bundle_name] ofType:@"bundle"]]; 26 | if (!bundle) 27 | return 0; 28 | 29 | if (!g_bundles) { 30 | g_bundles = [NSMutableArray arrayWithObject:bundle]; 31 | } else { 32 | [g_bundles addObject:bundle]; 33 | } 34 | 35 | return (int)g_bundles.count; 36 | } 37 | 38 | const char* fio_ios_resolve_path(char *outstr, int outstr_sz, int bundle_id, const char *filepath) 39 | { 40 | if (g_bundles) { 41 | char filename[DH_PATH_MAX]; 42 | char fileext[DH_PATH_MAX]; 43 | 44 | path_getfilename(filename, filepath); 45 | path_getfileext(fileext, filepath); 46 | 47 | NSUInteger index = (NSUInteger)(bundle_id-1); 48 | NSBundle *bundle = [g_bundles objectAtIndex:index]; 49 | 50 | NSString *path = [bundle pathForResource:[NSString stringWithUTF8String:filename] ofType:[NSString stringWithUTF8String:fileext]]; 51 | if (path) 52 | str_safecpy(outstr, outstr_sz, [path UTF8String]); 53 | else 54 | outstr[0] = 0; 55 | return outstr; 56 | } else { 57 | return nil; 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/core/wscript: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import os, sys, glob 4 | 5 | def build(bld): 6 | files = bld.path.ant_glob('*.c*') 7 | files.extend(bld.path.ant_glob('deps/cJSON/*.c')) 8 | files.extend(bld.path.ant_glob('deps/miniz/*.c')) 9 | files.extend(bld.path.ant_glob('deps/commander/*.c')) 10 | 11 | platform = bld.env.PLATFORM 12 | # Platform files 13 | if platform == 'win32': 14 | files.extend(bld.path.ant_glob('platform/win/*.c*')) 15 | elif platform.startswith('linux'): 16 | files.extend(bld.path.ant_glob('platform/posix/*.c')) 17 | files.extend(bld.path.ant_glob('platform/linux/*.c')) 18 | elif platform == 'darwin': 19 | files.extend(bld.path.ant_glob('platform/posix/*.c')) 20 | files.extend(bld.path.ant_glob('platform/osx/*.c')) 21 | 22 | # Libs 23 | libs = [] 24 | linkflags = [] 25 | frameworks = [] 26 | if platform.startswith('linux'): 27 | libs.extend(['rt', 'm']) 28 | elif platform == 'darwin': 29 | libs.extend(['stdc++']) 30 | elif platform == 'win32': 31 | linkflags.extend(['/NODEFAULTLIB:"LIBCMTD.LIB"', '/NODEFAULTLIB:"LIBCMT.LIB"']) 32 | libs.extend(['ws2_32', 'Shell32', 'Advapi32', 'User32']) 33 | 34 | defines = ['_CORE_EXPORT_'] 35 | 36 | # turn on file monitoring (+efsw lib) 37 | if bld.env.DFILEMON: 38 | libs.append('efsw') 39 | defines.append('_FILEMON_') 40 | 41 | # Version number 42 | vnum = '' 43 | if sys.platform.startswith('linux') or sys.platform == 'darwin': 44 | vnum = bld.env.VERSION 45 | 46 | # Copy under /bin for windows and /lib for others 47 | if sys.platform != 'win32': 48 | install_path = '${PREFIX}/lib' 49 | else: 50 | install_path = '${PREFIX}/bin' 51 | 52 | bld.shlib( 53 | source = files, 54 | includes = [\ 55 | os.path.join(bld.env.ROOTDIR, 'build'), 56 | os.path.join('..', '..', 'include'), 57 | 'deps' 58 | ], 59 | lib = libs, 60 | linkflags = linkflags, 61 | framework = frameworks, 62 | target = 'dhcore' + bld.env.SUFFIX, 63 | name = 'dhcore', 64 | export_includes = os.path.join(bld.env.ROOTDIR, 'include'), 65 | install_path = install_path, 66 | defines = defines, 67 | vnum = vnum) 68 | 69 | -------------------------------------------------------------------------------- /src/core/hwinfo.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include 17 | 18 | #include "dhcore/hwinfo.h" 19 | #include "dhcore/log.h" 20 | 21 | /* fwd (implemented in platform sources - see platform/${PLATFORM} */ 22 | void query_meminfo(struct hwinfo* info); 23 | void query_cpuinfo(struct hwinfo* info); 24 | void query_osinfo(struct hwinfo* info); 25 | uint query_clockspeed(uint cpu_idx); 26 | 27 | /* */ 28 | void hw_getinfo(struct hwinfo* info, uint flags) 29 | { 30 | memset(info, 0x00, sizeof(struct hwinfo)); 31 | 32 | if (BIT_CHECK(flags, HWINFO_MEMORY)) 33 | query_meminfo(info); 34 | 35 | if (BIT_CHECK(flags, HWINFO_CPU)) 36 | query_cpuinfo(info); 37 | 38 | if (BIT_CHECK(flags, HWINFO_OS)) 39 | query_osinfo(info); 40 | } 41 | 42 | void hw_printinfo(const struct hwinfo* info, uint flags) 43 | { 44 | if (BIT_CHECK(flags, HWINFO_CPU)) { 45 | log_print(LOG_INFO, " cpu:"); 46 | log_printf(LOG_INFO, "\tcpu vendor: %s", info->cpu_name); 47 | log_printf(LOG_INFO, "\tcpu clock-speed: %d(MHz)", info->cpu_clock); 48 | log_printf(LOG_INFO, "\tcpu features: %s", info->cpu_feat); 49 | log_printf(LOG_INFO, "\tcpu L2 cache: %d(kb)", info->cpu_cachesize*2); 50 | log_printf(LOG_INFO, "\tcpu physical cores: %d", info->cpu_pcore_cnt); 51 | log_printf(LOG_INFO, "\tcpu logical cores: %d", info->cpu_core_cnt); 52 | } 53 | 54 | if (BIT_CHECK(flags, HWINFO_MEMORY)) { 55 | log_print(LOG_INFO, " memory:"); 56 | log_printf(LOG_INFO, "\tsystem memory: %d(mb)", info->sys_mem/1024); 57 | log_printf(LOG_INFO, "\tfree memory: %d(mb)", info->sys_memfree/1024); 58 | } 59 | 60 | if (BIT_CHECK(flags, HWINFO_OS)) { 61 | log_print(LOG_INFO, " system:"); 62 | log_printf(LOG_INFO, "\tos: %s", info->os_name); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/core/core.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/core.h" 17 | #include "dhcore/json.h" 18 | #include "dhcore/file-io.h" 19 | #include "dhcore/timer.h" 20 | #include "dhcore/crash.h" 21 | #include "dhcore/net-socket.h" 22 | 23 | #ifdef _DEBUG_ 24 | #include 25 | #endif 26 | 27 | result_t core_init(uint flags) 28 | { 29 | if (BIT_CHECK(flags, CORE_INIT_CRASHDUMP)) { 30 | if (IS_FAIL(crash_init())) 31 | return RET_FAIL; 32 | } 33 | 34 | if (IS_FAIL(mem_init(BIT_CHECK(flags, CORE_INIT_TRACEMEM)))) 35 | return RET_FAIL; 36 | 37 | if (IS_FAIL(log_init())) 38 | return RET_FAIL; 39 | 40 | if (BIT_CHECK(flags, CORE_INIT_ERRORS)) { 41 | if (IS_FAIL(err_init())) 42 | return RET_FAIL; 43 | } 44 | 45 | rand_seed(); 46 | 47 | if (BIT_CHECK(flags, CORE_INIT_JSON)) { 48 | if (IS_FAIL(json_init())) 49 | return RET_FAIL; 50 | } 51 | 52 | if (BIT_CHECK(flags, CORE_INIT_FILEIO)) { 53 | if (IS_FAIL(fio_initmgr())) 54 | return RET_FAIL; 55 | } 56 | 57 | if (BIT_CHECK(flags, CORE_INIT_TIMER)) { 58 | if (IS_FAIL(timer_initmgr())) 59 | return RET_FAIL; 60 | } 61 | 62 | if (BIT_CHECK(flags, CORE_INIT_SOCKET)) { 63 | if (IS_FAIL(sock_init())) 64 | return RET_FAIL; 65 | } 66 | 67 | return RET_OK; 68 | } 69 | 70 | void core_release(int report_leaks) 71 | { 72 | sock_release(); 73 | 74 | timer_releasemgr(); 75 | 76 | fio_releasemgr(); 77 | 78 | json_release(); 79 | 80 | err_release(); 81 | 82 | log_release(); 83 | 84 | /* dump memory leaks before releasing memory manager and log 85 | * because memory leak report dumps leakage data to logger */ 86 | if (report_leaks) 87 | mem_reportleaks(); 88 | 89 | mem_release(); 90 | } 91 | -------------------------------------------------------------------------------- /include/dhcore/core.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef __CORE_H__ 17 | #define __CORE_H__ 18 | 19 | /** 20 | * @mainpage Core library API reference 21 | * Current version: 0.5.0 22 | */ 23 | 24 | /** 25 | * @defgroup core 26 | * Core library essential headers and init/release\n 27 | * Include "core.h" and use core_init, core_release to initialize basic core functionality 28 | * Example: @code 29 | * #include "dhcore/core.h" 30 | * int main() 31 | * { 32 | * core_init(CORE_INIT_ALL); 33 | * // continue with application and engine initialization and update 34 | * core_release(); 35 | * } 36 | * @endcode 37 | */ 38 | 39 | /* essential headers */ 40 | #include 41 | 42 | #include "types.h" 43 | #include "mem-mgr.h" 44 | #include "err.h" 45 | #include "log.h" 46 | #include "core-api.h" 47 | #include "numeric.h" 48 | #include "str.h" 49 | #include "path.h" 50 | #include "allocator.h" 51 | #include "util.h" 52 | 53 | /** 54 | * Core initialization flags 55 | * @ingroup core 56 | */ 57 | enum core_init_flags 58 | { 59 | CORE_INIT_TRACEMEM = (1<<0), 60 | CORE_INIT_CRASHDUMP = (1<<1), 61 | CORE_INIT_LOGGER = (1<<2), 62 | CORE_INIT_ERRORS = (1<<3), 63 | CORE_INIT_JSON = (1<<4), 64 | CORE_INIT_FILEIO = (1<<5), 65 | CORE_INIT_TIMER = (1<<6), 66 | CORE_INIT_SOCKET = (1<<7), 67 | CORE_INIT_ALL = 0xffffffff 68 | }; 69 | 70 | /** 71 | * Initializes/releases main @e core library components\n 72 | * It initializes following core library sub-systems: 73 | * - Memory manager 74 | * - Logger 75 | * - Error handling 76 | * - Random seed 77 | * - JSON parser 78 | * - File manager 79 | * - Timers 80 | * - Socket 81 | * @ingroup core 82 | */ 83 | CORE_API result_t core_init(uint flags); 84 | 85 | /** 86 | * Release core components 87 | * @param report_leaks report memory leaks to the logger 88 | * @ingroup core 89 | */ 90 | CORE_API void core_release(int report_leaks); 91 | 92 | #endif /* __CORE_H__ */ 93 | -------------------------------------------------------------------------------- /include/dhcore/path.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef PATH_H 17 | #define PATH_H 18 | 19 | #include "types.h" 20 | #include "core-api.h" 21 | #include "str.h" 22 | 23 | /** 24 | * convert windows-style path ("\\t\\win\\path") to unix-style path ("/t/win/path") 25 | * @ingroup str 26 | */ 27 | CORE_API char* path_tounix(char* outpath, const char* inpath); 28 | /** 29 | * convert unix-style path ("/t/unix/path") to windows-style path ("\\t\\unix\\path") 30 | * @ingroup str 31 | */ 32 | CORE_API char* path_towin(char* outpath, const char* inpath); 33 | /** 34 | * convert path to platform specific format 35 | * @ingroup str 36 | */ 37 | CORE_API char* path_norm(char* outpath, const char* inpath); 38 | /** 39 | * extract directory from the path 40 | * @ingroup str 41 | */ 42 | CORE_API char* path_getdir(char* outpath, const char* inpath); 43 | /** 44 | * extract filename from the path, without any extensions 45 | * @ingroup str 46 | */ 47 | CORE_API char* path_getfilename(char* outpath, const char* inpath); 48 | /** 49 | * extract file extension from the path 50 | * @ingroup str 51 | */ 52 | CORE_API char* path_getfileext(char* outpath, const char* inpath); 53 | /** 54 | * extract full filename (with extension) from path 55 | * @ingroup str 56 | */ 57 | CORE_API char* path_getfullfilename(char* outpath, const char* inpath); 58 | /** 59 | * go up one directory in path string 60 | * @ingroup str 61 | */ 62 | CORE_API char* path_goup(char* outpath, const char* inpath); 63 | /** 64 | * check if file is valid (exists) 65 | * @return returns 0 if nothing exists, 1 if it's a file, and 2 if directory (unix only) 66 | * @ingroup str 67 | */ 68 | CORE_API int path_exists(const char* inpath); 69 | 70 | /** 71 | * join multiple paths (or filenames) into one \n 72 | * Last argument should always be NULL to indicate that join arguments are finished 73 | * @ingroup str 74 | */ 75 | CORE_API char* path_join(char* outpath, const char* join0, const char* join1, ...); 76 | 77 | #endif // PATH_H 78 | -------------------------------------------------------------------------------- /src/core/static-vars.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2014, Sepehr Taghdisian (sep.tagh@gmail.com) 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/vec-math.h" 17 | #include "dhcore/color.h" 18 | #include "dhcore/prims.h" 19 | 20 | using namespace dh; 21 | 22 | // Vec3 23 | const Vec3 Vec3::UnitX(1.0f, 0.0f, 0.0f); 24 | const Vec3 Vec3::UnitY(0.0f, 1.0f, 0.0f); 25 | const Vec3 Vec3::UnitZ(0.0f, 0.0f, 1.0f); 26 | const Vec3 Vec3::UnitX_Neg(-1.0f, 0.0f, 0.0f); 27 | const Vec3 Vec3::UnitY_Neg(0.0f, -1.0f, 0.0f); 28 | const Vec3 Vec3::UnitZ_Neg(0.0f, 0.0f, -1.0f); 29 | const Vec3 Vec3::Zero(0.0f, 0.0f, 0.0f); 30 | 31 | // Quat 32 | const Quat Quat::Ident(0.0f, 0.0f, 0.0f, 1.0f); 33 | 34 | // Mat3 35 | const Mat3 Mat3::Ident(1.0f, 0.0f, 0.0f, 36 | 0.0f, 1.0f, 0.0f, 37 | 0.0f, 0.0f, 1.0f, 38 | 0.0f, 0.0f, 0.0f); 39 | 40 | // Mat4 41 | const Mat4 Mat4::Ident(1.0f, 0.0f, 0.0f, 0.0f, 42 | 0.0f, 1.0f, 0.0f, 0.0f, 43 | 0.0f, 0.0f, 1.0f, 0.0f, 44 | 0.0f, 0.0f, 0.0f, 1.0f); 45 | const Mat4 Mat4::Zero(0.0f, 0.0f, 0.0f, 0.0f, 46 | 0.0f, 0.0f, 0.0f, 0.0f, 47 | 0.0f, 0.0f, 0.0f, 0.0f, 48 | 0.0f, 0.0f, 0.0f, 0.0f); 49 | 50 | // Vec2 51 | const Vec2 Vec2::Zero(0.0f, 0.0f); 52 | const Vec2 Vec2::UnitX(1.0f, 0.0f); 53 | const Vec2 Vec2::UnitY(0.0f, 1.0f); 54 | 55 | // Vec2i 56 | const Vec2i Vec2i::Zero(0, 0); 57 | const Vec2i Vec2i::UnitX(1, 0); 58 | const Vec2i Vec2i::UnitY(0, 1); 59 | 60 | // Mat2 61 | const Mat2 Mat2::Ident(1.0f, 0.0f, 62 | 0.0f, 1.0f, 63 | 0.0f, 0.0f); 64 | 65 | // Color 66 | const Color Color::Black(0.0f, 0.0f, 0.0f); 67 | const Color Color::White(1.0f, 1.0f, 1.0f); 68 | const Color Color::Red(1.0f, 0.0f, 0.0f); 69 | const Color Color::Green(0.0f, 1.0f, 0.0f); 70 | const Color Color::Blue(0.0f, 0.0f, 1.0f); 71 | const Color Color::Yellow(1.0f, 1.0f, 0.0f); 72 | const Color Color::Purple(0.0f, 1.0f, 1.0f); 73 | const Color Color::Grey(0.3f, 0.3f, 0.3f); 74 | 75 | // Rect 76 | const Rect Rect::Zero(0, 0, 0, 0); 77 | 78 | // Rectf 79 | const Rectf Rectf::Zero(0, 0, 0, 0); 80 | -------------------------------------------------------------------------------- /include/dhcore/zip.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef __ZIP_H__ 17 | #define __ZIP_H__ 18 | 19 | /** 20 | * @defgroup zip Zip 21 | * Low-level buffer compression/decompression using miniz library (INFLATE)\n 22 | * @ingroup zip 23 | */ 24 | 25 | #include "types.h" 26 | #include "core-api.h" 27 | #include "file-io.h" 28 | 29 | struct mz_zip_archive_tag; 30 | typedef struct mz_zip_archive_tag* zip_t; 31 | 32 | /** 33 | * @ingroup zip 34 | */ 35 | enum compress_mode 36 | { 37 | COMPRESS_NORMAL = 0, 38 | COMPRESS_FAST, 39 | COMPRESS_BEST, 40 | COMPRESS_NONE 41 | }; 42 | 43 | /** 44 | * Roughly estimate maximum size of the compressed buffer, it's recommended that you evaluate 45 | * and allocated compressed buffer size with this function, then pass it to @e zip_compress 46 | * @param src_size Size (bytes) of uncompressed buffer 47 | * @return Estimated size of compressed target buffer 48 | * @see zip_compress 49 | * @ingroup zip 50 | */ 51 | CORE_API size_t zip_compressedsize(size_t src_size); 52 | 53 | /** 54 | * Compress buffer in memory 55 | * @param dest_buffer Destination buffer that will be filled with compressed data 56 | * @param dest_size Maximum size of destiniation buffer, usually fetched by @e zip_compressedsize 57 | * @return actual Size of compressed buffer, returns 0 if 58 | * @see zip_compressedsize 59 | * @ingroup zip 60 | */ 61 | CORE_API size_t zip_compress(void* dest_buffer, size_t dest_size, const void* buffer, size_t size, 62 | enum compress_mode mode); 63 | 64 | /** 65 | * Decompress buffer from memory 66 | * @param dest_buffer Uncompressed destination buffer 67 | * @param dest_size Uncompressed buffer size, this value should be saved when buffer is compressed 68 | * @return actual Size of uncompressed buffer 69 | * @ingroup zip 70 | */ 71 | CORE_API size_t zip_decompress(void* dest_buffer, size_t dest_size, const void* buffer, size_t size); 72 | 73 | CORE_API zip_t zip_open(const char *filepath); 74 | CORE_API zip_t zip_open_mem(const char *buff, size_t buff_sz); 75 | 76 | CORE_API void zip_close(zip_t zip); 77 | CORE_API file_t zip_getfile(zip_t zip, const char *filepath, struct allocator *alloc); 78 | 79 | #endif /* __ZIP_H__ */ 80 | -------------------------------------------------------------------------------- /src/core/platform/win/util-win.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/util.h" 17 | 18 | #if defined(_WIN_) 19 | 20 | #include "dhcore/win.h" 21 | #include 22 | #include 23 | 24 | #include "dhcore/err.h" 25 | #include "dhcore/str.h" 26 | #include "dhcore/path.h" 27 | 28 | char* util_getconfdir(char *outdir) 29 | { 30 | return path_join(outdir, util_getuserdir(outdir), "AppData", "Local", NULL); 31 | } 32 | 33 | char* util_getexedir(char* outpath) 34 | { 35 | GetModuleFileName(NULL, outpath, DH_PATH_MAX); 36 | path_getdir(outpath, outpath); 37 | return path_norm(outpath, outpath); 38 | } 39 | 40 | char* util_runcmd(const char* cmd) 41 | { 42 | ASSERT(0); 43 | return NULL; 44 | } 45 | 46 | char util_getch() 47 | { 48 | return _getch(); 49 | } 50 | 51 | char* util_getuserdir(char* outdir) 52 | { 53 | outdir[0] = 0; 54 | SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, outdir); 55 | return outdir; 56 | } 57 | 58 | char* util_gettempdir(char* outdir) 59 | { 60 | GetTempPath(DH_PATH_MAX, outdir); 61 | 62 | /* remove \\ from the end of the path */ 63 | size_t sz = strlen(outdir); 64 | if (sz > 0 && outdir[sz-1] == '\\') 65 | outdir[sz-1] = 0; 66 | return outdir; 67 | } 68 | 69 | int util_makedir(const char* dir) 70 | { 71 | return CreateDirectory(dir, NULL); 72 | } 73 | 74 | int util_copyfile(const char* dest, const char* src) 75 | { 76 | return CopyFile(src, dest, FALSE); 77 | } 78 | 79 | int util_pathisdir(const char* path) 80 | { 81 | DWORD atts = GetFileAttributes(path); 82 | if (atts == INVALID_FILE_ATTRIBUTES) 83 | return FALSE; 84 | return (atts & FILE_ATTRIBUTE_DIRECTORY) ? TRUE : FALSE; 85 | } 86 | 87 | void util_sleep(uint msecs) 88 | { 89 | Sleep(msecs); 90 | } 91 | 92 | int util_movefile(const char* dest, const char* src) 93 | { 94 | return MoveFileEx(src, dest, MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING); 95 | } 96 | 97 | int util_delfile(const char* filepath) 98 | { 99 | return DeleteFile(filepath); 100 | } 101 | 102 | #endif /* _WIN_ */ 103 | -------------------------------------------------------------------------------- /xcode/dhcore/dhcore.xcodeproj/xcuserdata/Sepul.xcuserdatad/xcschemes/dhcore.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 60 | 61 | 67 | 68 | 69 | 70 | 72 | 73 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/core/array.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/array.h" 17 | #include "dhcore/err.h" 18 | #include "dhcore/numeric.h" 19 | 20 | result_t arr_create(struct allocator* alloc, 21 | struct array* arr, 22 | int item_sz, int init_item_cnt, int expand_cnt, 23 | uint mem_id) 24 | { 25 | memset(arr, 0x00, sizeof(struct array)); 26 | arr->buffer = A_ALIGNED_ALLOC(alloc, item_sz*init_item_cnt, mem_id); 27 | if (arr->buffer == NULL) 28 | return RET_OUTOFMEMORY; 29 | 30 | arr->alloc = alloc; 31 | arr->expand_sz = expand_cnt; 32 | arr->item_cnt = 0; 33 | arr->item_sz = item_sz; 34 | arr->max_cnt = init_item_cnt; 35 | arr->mem_id = mem_id; 36 | 37 | return RET_OK; 38 | } 39 | 40 | void arr_destroy(struct array* arr) 41 | { 42 | ASSERT(arr != NULL); 43 | 44 | if (arr->buffer != NULL) { 45 | ASSERT(arr->alloc != NULL); 46 | A_ALIGNED_FREE(arr->alloc, arr->buffer); 47 | } 48 | } 49 | 50 | void* arr_add(struct array* arr) 51 | { 52 | result_t r = RET_OK; 53 | if (arr_needexpand(arr)) 54 | r = arr_expand(arr); 55 | 56 | if (r == RET_OK) { 57 | void* p = (uint8*)arr->buffer + arr->item_cnt*arr->item_sz; 58 | arr->item_cnt ++; 59 | return p; 60 | } else { 61 | return NULL; 62 | } 63 | } 64 | 65 | void* arr_add_batch(struct array *arr, int item_cnt) 66 | { 67 | if (arr->max_cnt < item_cnt + arr->item_cnt) { 68 | int newsz = aligni(item_cnt + arr->item_cnt, arr->expand_sz); 69 | 70 | arr->buffer = A_ALIGNED_REALLOC(arr->alloc, arr->buffer, newsz*arr->item_sz, arr->mem_id); 71 | if (arr->buffer == NULL) 72 | return NULL; 73 | arr->max_cnt = newsz; 74 | } 75 | 76 | void *p = (uint8*)arr->buffer + arr->item_cnt*arr->item_sz; 77 | arr->item_cnt += item_cnt; 78 | 79 | return p; 80 | } 81 | 82 | result_t arr_expand(struct array* arr) 83 | { 84 | ASSERT(arr != NULL); 85 | ASSERT(arr->alloc != NULL); 86 | ASSERT(arr->buffer != NULL); 87 | 88 | /* reallocate */ 89 | int newsz = arr->max_cnt + arr->expand_sz; 90 | arr->buffer = A_ALIGNED_REALLOC(arr->alloc, arr->buffer, newsz*arr->item_sz, arr->mem_id); 91 | if (arr->buffer == NULL) 92 | return RET_OUTOFMEMORY; 93 | 94 | arr->max_cnt = newsz; 95 | return RET_OK; 96 | } 97 | 98 | 99 | -------------------------------------------------------------------------------- /include/dhcore/hwinfo.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef __HWINFO_H__ 17 | #define __HWINFO_H__ 18 | 19 | #include "types.h" 20 | #include "core-api.h" 21 | 22 | enum hwinfo_flags 23 | { 24 | HWINFO_MEMORY = (1<<0), 25 | HWINFO_CPU = (1<<2), 26 | HWINFO_OS = (1<<3), 27 | HWINFO_ALL = 0xFFFFFFFF 28 | }; 29 | 30 | /** 31 | * CPU Type 32 | * @ingroup eng 33 | */ 34 | enum hwinfo_cpu_type 35 | { 36 | HWINFO_CPU_UNKNOWN, 37 | HWINFO_CPU_INTEL, 38 | HWINFO_CPU_AMD 39 | }; 40 | 41 | /** 42 | * OS Type 43 | * @ingroup eng 44 | */ 45 | enum hwinfo_os_type 46 | { 47 | HWINFO_OS_UNKNOWN, 48 | HWINFO_OS_WIN9X, 49 | HWINFO_OS_WINNT, 50 | HWINFO_OS_LINUX, 51 | HWINFO_OS_WIN2K, 52 | HWINFO_OS_WINXP, 53 | HWINFO_OS_WINVISTA, 54 | HWINFO_OS_WIN7, 55 | HWINFO_OS_WIN8, 56 | HWINFO_OS_OSX 57 | }; 58 | 59 | /** 60 | * CPU Caps 61 | * @ingroup eng 62 | */ 63 | enum hwinfo_cpu_ext 64 | { 65 | HWINFO_CPUEXT_MMX = (1<<0), /**< MMX Instructions support */ 66 | HWINFO_CPUEXT_SSE = (1<<1), /**< SSE Instructions support */ 67 | HWINFO_CPUEXT_SSE2 = (1<<2), /**< SSE2 Instructions support */ 68 | HWINFO_CPUEXT_SSE3 = (1<<3), /**< SSE3 Instructions support */ 69 | HWINFO_CPUEXT_SSE4 = (1<<4) /**< SSE4 Instructions support */ 70 | }; 71 | 72 | /** 73 | * Hardware information structure 74 | * @ingroup eng 75 | */ 76 | struct hwinfo 77 | { 78 | char cpu_name[128]; /**< CPU vendor name */ 79 | char cpu_feat[128]; /**< CPU Features string, each feature is separated with space */ 80 | char os_name[128]; /**< Running OS Name */ 81 | size_t sys_mem; /**< Available total system memory (in Kb) */ 82 | size_t sys_memfree; /**< Available free system memory (in Kb) */ 83 | uint cpu_clock; /**< CPU clock rate (in MHZ) */ 84 | uint cpu_cachesize; /**< CPU Cache size */ 85 | uint cpu_cacheline; /**< CPU Cache line size */ 86 | int cpu_core_cnt; /**< Total count of cpu cores (logical) */ 87 | int cpu_pcore_cnt; /**< Total count of physical cpu cores */ 88 | uint cpu_caps; /**< Combination of known CPU Caps (@see hwinfo_cpu_ext) */ 89 | enum hwinfo_cpu_type cpu_type; /**< CPU Type (@see hwinfo_cpu_type) */ 90 | enum hwinfo_os_type os_type; /**< OS Type (@see hwinfo_os_type) */ 91 | }; 92 | 93 | CORE_API void hw_getinfo(struct hwinfo* info, uint flags); 94 | CORE_API void hw_printinfo(const struct hwinfo* info, uint flags); 95 | 96 | #endif /* __HWINFO_H__ */ 97 | -------------------------------------------------------------------------------- /src/core/std-math.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/std-math.h" 17 | #include "dhcore/mem-mgr.h" 18 | 19 | union bits_t 20 | { 21 | float f; 22 | int si; 23 | uint ui; 24 | }; 25 | 26 | #define SHIFT 13 27 | #define SHIFT_SIGN 16 28 | 29 | #define INFN (0x7F800000) 30 | #define MAXN (0x477FE000) 31 | #define MINN (0x38800000) 32 | #define SIGNN (0x80000000) 33 | 34 | #define INFC (INFN >> SHIFT) 35 | #define NANN ((INFC + 1) << SHIFT) 36 | #define MAXC (MAXN >> SHIFT) 37 | #define MINC (MINN >> SHIFT) 38 | #define SIGNC (SIGNN >> SHIFT_SIGN) 39 | 40 | #define MULN (0x52000000) 41 | #define MULC (0x33800000) 42 | 43 | #define SUBC (0x003FF) 44 | #define NORC (0x00400) 45 | 46 | #define MAXD (INFC - MAXC - 1) 47 | #define MIND (MINC - SUBC - 1) 48 | 49 | /*************************************************************************************************/ 50 | uint16 math_ftou16(float n) 51 | { 52 | union bits_t v, s; 53 | v.f = n; 54 | uint sign = v.si & SIGNN; 55 | v.si ^= sign; 56 | sign >>= SHIFT_SIGN; /* logical SHIFT */ 57 | s.si = MULN; 58 | s.si = (int)(s.f * v.f); /* correct subnormals */ 59 | v.si ^= (s.si ^ v.si) & -(MINN > v.si); 60 | v.si ^= (INFN ^ v.si) & -((INFN > v.si) & (v.si > MAXN)); 61 | v.si ^= (NANN ^ v.si) & -((NANN > v.si) & (v.si > INFN)); 62 | v.ui >>= SHIFT; /* logical SHIFT */ 63 | v.si ^= ((v.si - MAXD) ^ v.si) & -(v.si > MAXC); 64 | v.si ^= ((v.si - MIND) ^ v.si) & -(v.si > SUBC); 65 | return v.ui | sign; 66 | } 67 | 68 | float math_u16tof(uint16 n) 69 | { 70 | union bits_t v; 71 | v.ui = n; 72 | int sign = v.si & SIGNC; 73 | v.si ^= sign; 74 | sign <<= SHIFT_SIGN; 75 | v.si ^= ((v.si + MIND) ^ v.si) & -(v.si > SUBC); 76 | v.si ^= ((v.si + MAXD) ^ v.si) & -(v.si > MAXC); 77 | union bits_t s; 78 | s.si = MULC; 79 | s.f *= v.si; 80 | int mask = -(NORC > v.si); 81 | v.si <<= SHIFT; 82 | v.si ^= (s.si ^ v.si) & mask; 83 | v.si |= sign; 84 | return v.f; 85 | } 86 | 87 | /* exponential decay function */ 88 | float math_decay(float x, float real_x, float springiness, float dt) 89 | { 90 | fl64 d = 1 - exp(log(0.5)*springiness*dt); 91 | return (float)(x + (real_x - x)*d); 92 | } -------------------------------------------------------------------------------- /src/test/test-freelist.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore-test.h" 17 | #include "dhcore/core.h" 18 | #include "dhcore/freelist-alloc.h" 19 | #include "dhcore/timer.h" 20 | #include "dhcore/hash.h" 21 | 22 | void test_freelist() 23 | { 24 | const uint item_cnt = 100000; 25 | const uint max_size = item_cnt * 1024; 26 | void** ptrs = (void**)ALLOC(item_cnt*sizeof(void*), 0); 27 | uint* h = (uint*)ALLOC(item_cnt*sizeof(uint), 0); 28 | size_t* sizes = (size_t*)ALLOC(item_cnt*sizeof(size_t), 0); 29 | 30 | uint free_cnt = 0; 31 | 32 | struct freelist_alloc freelist; 33 | struct allocator alloc; 34 | mem_freelist_create(mem_heap(), &freelist, max_size, 0); 35 | mem_freelist_bindalloc(&freelist, &alloc); 36 | 37 | uint64 t1 = timer_querytick(); 38 | 39 | log_printf(LOG_TEXT, "allocating %d items from freelist (with hash validation)...", item_cnt); 40 | for (uint i = 0; i < item_cnt; i++) { 41 | int s = rand_geti(8, 1024); 42 | ASSERT(s <= 1024); 43 | ptrs[i] = A_ALLOC(&alloc, s, 6); 44 | ASSERT(ptrs[i]); 45 | 46 | if (i > 0 && rand_flipcoin(50)) { 47 | uint idx_tofree = rand_geti(0, i-1); 48 | if (ptrs[idx_tofree] != NULL) { 49 | A_FREE(&alloc, ptrs[idx_tofree]); 50 | ptrs[idx_tofree] = NULL; 51 | } 52 | } 53 | 54 | // random fill the buffer 55 | memset(ptrs[i], 0x00, s); 56 | 57 | h[i] = hash_murmur32(ptrs[i], s, 100); 58 | sizes[i] = s; 59 | } 60 | 61 | // check if the remaining buffers are untouched 62 | for (uint i = 0; i < item_cnt; i++) { 63 | if (ptrs[i] != NULL) { 64 | #if defined(_DEBUG_) 65 | uint hh = hash_murmur32(ptrs[i], sizes[i], 100); 66 | ASSERT(h[i] == hh); 67 | #endif 68 | } 69 | } 70 | 71 | for (uint i = 0; i < item_cnt; i++) { 72 | //if (rand_flipcoin(50)) { 73 | if (ptrs[i] != NULL) { 74 | A_FREE(&alloc, ptrs[i]); 75 | free_cnt ++; 76 | ptrs[i] = NULL; 77 | } 78 | //} 79 | } 80 | 81 | /* report leaks */ 82 | uint leaks_cnt = mem_freelist_getleaks(&freelist, NULL); 83 | if (leaks_cnt > 0) 84 | log_printf(LOG_TEXT, "%d leaks found", leaks_cnt); 85 | 86 | mem_freelist_destroy(&freelist); 87 | log_print(LOG_TEXT, "done."); 88 | log_printf(LOG_TEXT, "took %f ms.", 89 | timer_calctm(t1, timer_querytick())*1000.0f); 90 | 91 | FREE(ptrs); 92 | FREE(h); 93 | FREE(sizes); 94 | } 95 | 96 | -------------------------------------------------------------------------------- /include/dhcore/variant.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2013, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef __VARIANT_H__ 17 | #define __VARIANT_H__ 18 | 19 | #include "types.h" 20 | #include "core-api.h" 21 | 22 | #if defined(_MSVC_) 23 | #pragma warning(disable: 662) 24 | #endif 25 | 26 | enum variant_type 27 | { 28 | VAR_TYPE_BOOL = 1, 29 | VAR_TYPE_INT = 2, 30 | VAR_TYPE_UINT = 3, 31 | VAR_TYPE_FLOAT = 4, 32 | VAR_TYPE_FLOAT2 = 5, 33 | VAR_TYPE_FLOAT3 = 6, 34 | VAR_TYPE_FLOAT4 = 7, 35 | VAR_TYPE_INT2 = 8, 36 | VAR_TYPE_INT3 = 9, 37 | VAR_TYPE_INT4 = 10, 38 | VAR_TYPE_STRING = 11, 39 | VAR_TYPE_NULL = 0 40 | }; 41 | 42 | struct variant 43 | { 44 | enum variant_type type; 45 | 46 | union { 47 | int b; 48 | int i; 49 | uint ui; 50 | float f; 51 | float fv[4]; 52 | int iv[4]; 53 | char str[16]; 54 | }; 55 | }; 56 | 57 | CORE_API struct variant* var_setv(struct variant* rv, const struct variant* v); 58 | CORE_API struct variant* var_setb(struct variant* v, int b); 59 | CORE_API struct variant* var_seti(struct variant* v, int i); 60 | CORE_API struct variant* var_setui(struct variant* v, uint ui); 61 | CORE_API struct variant* var_setf(struct variant* v, float f); 62 | CORE_API struct variant* var_set2fv(struct variant* v, const float* fv); 63 | CORE_API struct variant* var_set3fv(struct variant* v, const float* fv); 64 | CORE_API struct variant* var_set4fv(struct variant* v, const float* fv); 65 | CORE_API struct variant* var_set2iv(struct variant* v, const int* iv); 66 | CORE_API struct variant* var_set3iv(struct variant* v, const int* iv); 67 | CORE_API struct variant* var_set4iv(struct variant* v, const int* iv); 68 | CORE_API struct variant* var_set2f(struct variant* v, float x, float y); 69 | CORE_API struct variant* var_set3f(struct variant* v, float x, float y, float z); 70 | CORE_API struct variant* var_set4f(struct variant* v, float x, float y, float z, float w); 71 | CORE_API struct variant* var_set2i(struct variant* v, int x, int y); 72 | CORE_API struct variant* var_set3i(struct variant* v, int x, int y, int z); 73 | CORE_API struct variant* var_set4i(struct variant* v, int x, int y, int z, int w); 74 | CORE_API struct variant* var_sets(struct variant* v, const char* str); 75 | CORE_API const char* var_gets(const struct variant* v); 76 | 77 | CORE_API int var_geti(const struct variant* v); 78 | CORE_API uint var_getui(const struct variant* v); 79 | CORE_API float var_getf(const struct variant* v); 80 | CORE_API int var_getb(const struct variant* v); 81 | CORE_API const float* var_getfv(const struct variant* v); 82 | CORE_API const int* var_getiv(const struct variant* v); 83 | CORE_API const char* var_gets(const struct variant* v); 84 | 85 | #endif /* __VARIANT_H__ */ 86 | 87 | -------------------------------------------------------------------------------- /include/dhcore/std-math.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | 17 | #ifndef __STDMATH_H__ 18 | #define __STDMATH_H__ 19 | 20 | #include 21 | #include "types.h" 22 | #include "core-api.h" 23 | #include "numeric.h" 24 | 25 | /** 26 | * @defgroup stdmath Std-math 27 | */ 28 | 29 | /** 30 | * check if float value is NAN 31 | * @ingroup stdmath 32 | */ 33 | INLINE int math_isnan(float n) 34 | { 35 | return (n != n); 36 | } 37 | 38 | /** 39 | * round float value to it's closest value 40 | * @ingroup stdmath 41 | */ 42 | INLINE float math_round(float n) 43 | { 44 | return (n > 0.0f) ? floorf(n + 0.5f) : ceilf(n - 0.5f); 45 | } 46 | 47 | /** 48 | * checks equality of two floating-point values with a tolerance 49 | * @ingroup stdmath 50 | */ 51 | INLINE int math_isequal(float a, float b) 52 | { 53 | if (fabs(a-b) < EPSILON) 54 | return TRUE; 55 | 56 | float err = 0.0f; 57 | if (fabsf(b) > fabsf(a)) 58 | err = fabsf((a-b)/b); 59 | else 60 | err = fabsf((a-b)/a); 61 | 62 | return (err < EPSILON); 63 | } 64 | 65 | /** 66 | * checks if floating-point value is zero 67 | * @ingroup stdmath 68 | */ 69 | INLINE int math_iszero(float n) 70 | { 71 | return fabs(n) < EPSILON; 72 | } 73 | 74 | /** 75 | * converts radians to degrees 76 | * @ingroup stdmath 77 | */ 78 | INLINE float math_todeg(float rad) 79 | { 80 | return 180.0f * rad / PI; 81 | } 82 | 83 | /* 84 | * converts degrees to radians 85 | * @ingroup stdmath 86 | */ 87 | INLINE float math_torad(float deg) 88 | { 89 | return deg * PI / 180.0f; 90 | } 91 | 92 | /** 93 | * returns the sign of float value 94 | * @return 1.0 if 'n' is positive, -1.0 if 'n' is negative and 0 if 'n' is zero 95 | * @ingroup stdmath 96 | */ 97 | INLINE float math_sign(float n) 98 | { 99 | if (n > EPSILON) return 1.0f; 100 | else if (n < -EPSILON) return -1.0f; 101 | else return 0.0f; 102 | } 103 | 104 | /** 105 | * Encodes 32bit float value to uint16 106 | * @ingroup stdmath 107 | */ 108 | CORE_API uint16 math_ftou16(float n); 109 | 110 | /** 111 | * Decodes uint16 value to 32bit floating point value 112 | * @ingroup stdmath 113 | */ 114 | CORE_API float math_u16tof(uint16 n); 115 | 116 | /** 117 | * Safe ACos 118 | * @return PI if x is less than -1.0f, 0.0f if x is more than 1.0f, and acos(x) if x is within range 119 | */ 120 | INLINE float math_acosf(float x) 121 | { 122 | if (x <= -1.0f) return PI; 123 | if (x >= 1.0f) return 0.0f; 124 | return acosf(x); 125 | } 126 | 127 | /** 128 | * Apply decay function 129 | * @param 130 | * @param 131 | * @return 132 | */ 133 | CORE_API float math_decay(float x, float real_x, float springiness, float dt); 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /src/core/zip.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/err.h" 17 | #include "dhcore/mem-mgr.h" 18 | #include "dhcore/zip.h" 19 | #include "miniz/miniz.h" 20 | 21 | /* */ 22 | size_t zip_compressedsize(size_t src_size) 23 | { 24 | return (size_t)compressBound((mz_ulong)src_size); 25 | } 26 | 27 | size_t zip_compress(void* dest_buffer, size_t dest_size, 28 | const void* buffer, size_t size, enum compress_mode mode) 29 | { 30 | int c_level; 31 | switch (mode) { 32 | case COMPRESS_NORMAL: c_level = Z_DEFAULT_COMPRESSION; break; 33 | case COMPRESS_FAST: c_level = Z_BEST_SPEED; break; 34 | case COMPRESS_BEST: c_level = Z_BEST_COMPRESSION; break; 35 | case COMPRESS_NONE: c_level = Z_NO_COMPRESSION; break; 36 | default: c_level = Z_DEFAULT_COMPRESSION; break; 37 | } 38 | 39 | uLongf dsize = (uLongf)dest_size; 40 | int r = compress2((Bytef*)dest_buffer, &dsize, (const Bytef*)buffer, (uLongf)size, c_level); 41 | return (r == Z_OK) ? (size_t)dsize : 0; 42 | } 43 | 44 | size_t zip_decompress(void* dest_buffer, size_t dest_size, const void* buffer, size_t size) 45 | { 46 | uLongf dsize = (uLongf)dest_size; 47 | int r = uncompress((Bytef*)dest_buffer, &dsize, (Bytef*)buffer, (uLongf)size); 48 | return (r == Z_OK) ? (size_t)dsize : 0; 49 | } 50 | 51 | zip_t zip_open(const char *filepath) 52 | { 53 | mz_zip_archive *zip = (mz_zip_archive*)ALLOC(sizeof(mz_zip_archive), 0); 54 | if (zip == NULL) 55 | return NULL; 56 | memset(zip, 0x00, sizeof(mz_zip_archive)); 57 | 58 | if (!mz_zip_reader_init_file(zip, filepath, 0)) { 59 | FREE(zip); 60 | return NULL; 61 | } 62 | 63 | return zip; 64 | } 65 | 66 | zip_t zip_open_mem(const char *buff, size_t buff_sz) 67 | { 68 | mz_zip_archive *zip = (mz_zip_archive*)ALLOC(sizeof(mz_zip_archive), 0); 69 | if (zip == NULL) 70 | return NULL; 71 | memset(zip, 0x00, sizeof(mz_zip_archive)); 72 | 73 | if (!mz_zip_reader_init_mem(zip, buff, buff_sz, 0)) { 74 | FREE(zip); 75 | return NULL; 76 | } 77 | 78 | return zip; 79 | } 80 | 81 | void zip_close(zip_t zip) 82 | { 83 | ASSERT(zip); 84 | mz_zip_reader_end(zip); 85 | } 86 | 87 | file_t zip_getfile(zip_t zip, const char *filepath, struct allocator *alloc) 88 | { 89 | int idx = mz_zip_reader_locate_file(zip, filepath, NULL, 0); 90 | if (idx == -1) 91 | return NULL; 92 | 93 | mz_zip_archive_file_stat stat; 94 | mz_zip_reader_file_stat(zip, idx, &stat); 95 | 96 | void *buff = A_ALLOC(alloc, (size_t)stat.m_uncomp_size, 0); 97 | if (buff == NULL) 98 | return NULL; 99 | if (!mz_zip_reader_extract_to_mem(zip, idx, buff, (size_t)stat.m_uncomp_size, 0)) { 100 | A_FREE(alloc, buff); 101 | return NULL; 102 | } 103 | 104 | return fio_attachmem(alloc, buff, (size_t)stat.m_uncomp_size, filepath, 0); 105 | } 106 | -------------------------------------------------------------------------------- /src/core/timer.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/timer.h" 17 | #include "dhcore/mem-mgr.h" 18 | #include "dhcore/err.h" 19 | 20 | /* types */ 21 | struct timer_mgr 22 | { 23 | uint64 prev_tick; 24 | float scale; 25 | struct pool_alloc timer_pool; 26 | struct linked_list* timers; 27 | }; 28 | 29 | /************************************************************************************************* 30 | * globals 31 | */ 32 | static struct timer_mgr* g_tm = NULL; 33 | 34 | // Fwd 35 | void timer_queryfreq(); 36 | 37 | /*************************************************************************************************/ 38 | result_t timer_initmgr() 39 | { 40 | if (g_tm != NULL) 41 | return RET_FAIL; 42 | g_tm = (struct timer_mgr*)ALLOC(sizeof(struct timer_mgr), 0); 43 | if (g_tm == NULL) 44 | return RET_OUTOFMEMORY; 45 | memset(g_tm, 0x00, sizeof(struct timer_mgr)); 46 | 47 | g_tm->scale = 1.0f; 48 | timer_queryfreq(); 49 | 50 | /* memory pool for timers */ 51 | return mem_pool_create(mem_heap(), &g_tm->timer_pool, sizeof(struct timer), 20, 0); 52 | } 53 | 54 | void timer_releasemgr() 55 | { 56 | if (g_tm != NULL) { 57 | mem_pool_destroy(&g_tm->timer_pool); 58 | FREE(g_tm); 59 | g_tm = NULL; 60 | } 61 | } 62 | 63 | struct timer* timer_createinstance(int start) 64 | { 65 | struct timer* tm = (struct timer*)mem_pool_alloc(&g_tm->timer_pool); 66 | ASSERT(tm != NULL); 67 | memset(tm, 0x00, sizeof(struct timer)); 68 | 69 | list_add(&g_tm->timers, &tm->node, tm); 70 | if (start) 71 | tm->rate = 1.0f; 72 | 73 | return tm; 74 | } 75 | 76 | void timer_destroyinstance(struct timer* tm) 77 | { 78 | list_remove(&g_tm->timers, &tm->node); 79 | memset(tm, 0x00, sizeof(struct timer)); 80 | mem_pool_free(&g_tm->timer_pool, tm); 81 | } 82 | 83 | void timer_update(uint64 tick) 84 | { 85 | if (g_tm->prev_tick == 0) 86 | g_tm->prev_tick = tick; 87 | 88 | double dt = timer_calctm(g_tm->prev_tick, tick); 89 | dt *= g_tm->scale; 90 | g_tm->prev_tick = tick; 91 | float dtf = (float)dt; 92 | 93 | /* move through the linked-list of timers and update them */ 94 | struct linked_list* tm_node = g_tm->timers; 95 | while (tm_node != NULL) { 96 | struct timer* tm = (struct timer*)tm_node->data; 97 | tm->dt = dtf * tm->rate; 98 | tm->t += tm->dt; 99 | tm_node = tm_node->next; 100 | } 101 | } 102 | 103 | void timer_pauseall() 104 | { 105 | struct linked_list* tm_node = g_tm->timers; 106 | while (tm_node != NULL) { 107 | struct timer* tm = (struct timer*)tm_node->data; 108 | TIMER_PAUSE(tm); 109 | tm_node = tm_node->next; 110 | } 111 | } 112 | 113 | void timer_resumeall() 114 | { 115 | struct linked_list* tm_node = g_tm->timers; 116 | while (tm_node != NULL) { 117 | struct timer* tm = (struct timer*)tm_node->data; 118 | TIMER_START(tm); 119 | tm_node = tm_node->next; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /include/dhcore/log.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | 17 | #ifndef __LOG_H__ 18 | #define __LOG_H__ 19 | 20 | #include "types.h" 21 | #include "core-api.h" 22 | 23 | #define LOG_STDOUT_PADDING "50" 24 | 25 | /** 26 | * @defgroup log Logger 27 | * Performs engine logging to console, file, debugger or any custom implementation 28 | */ 29 | 30 | /** 31 | * @ingroup log 32 | */ 33 | enum log_type 34 | { 35 | LOG_TEXT = 0, 36 | LOG_ERROR = 1, 37 | LOG_WARNING = 2, 38 | LOG_INFO = 3, 39 | LOG_LOAD = 4, 40 | LOG_PROGRESS = 5, 41 | LOG_PROGRESS_RESULT = 6 42 | }; 43 | 44 | enum log_progress_result 45 | { 46 | LOG_PROGRESS_OK, 47 | LOG_PROGRESS_FATAL, 48 | LOG_PROGRESS_NONFATAL 49 | }; 50 | 51 | /** 52 | * @ingroup log 53 | */ 54 | struct log_stats 55 | { 56 | long volatile msgs_cnt; 57 | long volatile errors_cnt; 58 | long volatile warnings_cnt; 59 | }; 60 | 61 | /** 62 | * custom log function callback \n 63 | * @see log_outputfunc @ingroup log 64 | */ 65 | typedef void (*pfn_log_handler)(enum log_type type, const char* text, void* param); 66 | 67 | /* set output options of the logger 68 | ** 69 | * set log output to console 70 | * @ingroup log 71 | */ 72 | CORE_API result_t log_outputconsole(int enable); 73 | /** 74 | * set log output to text file 75 | * @ingroup log 76 | */ 77 | CORE_API result_t log_outputfile(int enable, const char* log_filepath); 78 | /** 79 | * set log output to debugger 80 | * @ingroup log 81 | */ 82 | CORE_API result_t log_outputdebugger(int enable); 83 | /** 84 | * set log output to custom function 85 | * @ingroup log 86 | */ 87 | CORE_API result_t log_outputfunc(int enable, pfn_log_handler log_fn, void* param); 88 | 89 | /* check output options of logger 90 | ** 91 | * checks if log output is console 92 | * @ingroup log 93 | */ 94 | CORE_API int log_isconsole(); 95 | /** 96 | * checks if log output is text file 97 | * @ingroup log 98 | */ 99 | CORE_API int log_isfile(); 100 | /** 101 | * checks if log output is debugger 102 | * @ingroup log 103 | */ 104 | CORE_API int log_isdebugger(); 105 | 106 | /** 107 | * checks if log output is custom function 108 | * @ingroup log 109 | */ 110 | CORE_API int log_isoutputfunc(); 111 | 112 | /** 113 | * print text to the logger 114 | * @param type type of log message (@see log_type) 115 | * @ingroup log 116 | */ 117 | CORE_API void log_print(enum log_type type, const char* text); 118 | /** 119 | * print formatted text to the logger 120 | * @param type type of log message (@see log_type) 121 | * @ingroup log 122 | */ 123 | CORE_API void log_printf(enum log_type type, const char* fmt, ...); 124 | 125 | /** 126 | * get log statistics, count number of errors/warnings/... 127 | * @see log_stats @ingroup log 128 | */ 129 | CORE_API void log_getstats(struct log_stats* stats); 130 | 131 | /** 132 | * @brief log_endprogress 133 | * @param res 134 | */ 135 | CORE_API void log_endprogress(enum log_progress_result res); 136 | 137 | /* */ 138 | result_t log_init(); 139 | void log_release(); 140 | 141 | #endif /*__LOG_H__*/ 142 | -------------------------------------------------------------------------------- /include/dhcore/stack.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | 17 | #ifndef __STACK_H__ 18 | #define __STACK_H__ 19 | 20 | #include "types.h" 21 | 22 | /** 23 | * @defgroup stack Stack 24 | * FILO (first-in-last-out) stack structure\n 25 | * Usage :\n 26 | * @code 27 | * // stack must be wrapped inside your own structures/objects 28 | * struct myobj 29 | * { 30 | * int data; 31 | * struct stack node; 32 | * }; 33 | * 34 | * // we hold the master stack (pointer) to keep track of the stack 35 | * struct stack* root = NULL; 36 | * 37 | * struct myobj sobj1; 38 | * struct myobj sobj2; 39 | * memset(&sobj1, 0x00, sizeof(sobj1)); 40 | * memset(&sobj2, 0x00, sizeof(sobj2)); 41 | * 42 | * sobj1.data = 1; 43 | * sobj2.data = 2; 44 | * 45 | * stack_push(&root, &sobj1.node, &sobj1); 46 | * stack_push(&root, &sobj2.node, &sobj2); 47 | * 48 | * // ... 49 | * // pop from stack 50 | * struct stack* sitem; 51 | * while ((sitem = stack_pop(&root)) != NULL) { 52 | * struct myobj* obj = sitem->data; 53 | * printf("data: %d\n", obj->data); 54 | * } 55 | * @endcode 56 | * @see stack_push 57 | * @see stack_pop 58 | * @ingroup stack 59 | */ 60 | 61 | struct stack 62 | { 63 | struct stack* prev; 64 | void* data; 65 | 66 | #ifdef __cplusplus 67 | stack() : prev(NULL), data(NULL) {} 68 | #endif 69 | }; 70 | 71 | 72 | /** 73 | * Push item into stack 74 | * @param pstack pointer to root stack item (can be NULL) 75 | * @param item stack item to be pushed 76 | * @param data custom data to keep in stack item, mostly owner of the current stack item 77 | * @ingroup stack 78 | */ 79 | INLINE void stack_push(struct stack** pstack, struct stack* item, void* data) 80 | { 81 | item->prev = *pstack; 82 | *pstack = item; 83 | item->data = data; 84 | } 85 | 86 | /** 87 | * Pop item from stack 88 | * @param pstack pointer to root stack item, will be NULL if last item is popped 89 | * @return popped stack item, look in ->data member variable for owner data 90 | * @ingroup stack 91 | */ 92 | INLINE struct stack* stack_pop(struct stack** pstack) 93 | { 94 | struct stack* item = *pstack; 95 | if (*pstack != NULL) { 96 | *pstack = (*pstack)->prev; 97 | item->prev = NULL; 98 | } 99 | return item; 100 | } 101 | 102 | #ifdef __cplusplus 103 | namespace dh { 104 | 105 | // _T: container type for stack's data 106 | template 107 | class Stack 108 | { 109 | private: 110 | Stack<_T> *m_prev = nullptr; 111 | _T m_data; 112 | 113 | public: 114 | Stack() = default; 115 | 116 | _T data() const { return m_data; } 117 | Stack<_T>* prev() const { return m_prev; } 118 | 119 | static void push(Stack<_T> **pstack, Stack<_T> *new_item, _T data) 120 | { 121 | new_item->m_prev = *pstack; 122 | *pstack = new_item; 123 | new_item->m_data = data; 124 | } 125 | 126 | static Stack<_T>* pop(Stack<_T> **pstack) 127 | { 128 | Stack<_T> *item = *pstack; 129 | if (*pstack) { 130 | *pstack = (*pstack)->m_prev; 131 | item->m_prev = nullptr; 132 | } 133 | return item; 134 | } 135 | }; 136 | 137 | } 138 | #endif 139 | 140 | #endif /* __STACK_H__ */ 141 | -------------------------------------------------------------------------------- /src/test/dhcore-test.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include 17 | #include 18 | 19 | #include "dhcore/core.h" 20 | #include "dhcore/commander.h" 21 | 22 | #include "dhcore-test.h" 23 | 24 | typedef void (*pfn_test)(); 25 | 26 | struct unit_test_desc 27 | { 28 | pfn_test test_fn; 29 | const char* name; 30 | const char* desc; 31 | }; 32 | 33 | static const struct unit_test_desc g_tests[] = { 34 | {test_heap, "heap", "Heap allocation"}, 35 | {test_freelist, "freelist", "Freelist allocator"}, 36 | {test_json, "json", "JSON parser"}, 37 | {test_mempool, "pool", "Pool allocator"}, 38 | {test_thread, "thread", "Basic threads"}, 39 | {test_taskmgr, "taskmgr", "Task manager"}, 40 | {test_hashtable, "hashtable_fixed", "Hash tables (fixed)"} 41 | /*, {test_efsw, "watcher", "filesystem monitoring"}*/ 42 | }; 43 | 44 | static int g_testidx = -1; 45 | 46 | /* */ 47 | void cmd_gettest(command_t* cmd, void* param) 48 | { 49 | if (str_isequal_nocase(cmd->arg, "heap")) { 50 | g_testidx = 0; 51 | } else if (str_isequal_nocase(cmd->arg, "freelist")) { 52 | g_testidx = 1; 53 | } else if (str_isequal_nocase(cmd->arg, "json")) { 54 | g_testidx = 2; 55 | } else if (str_isequal_nocase(cmd->arg, "pool")) { 56 | g_testidx = 3; 57 | } else if (str_isequal_nocase(cmd->arg, "thread")) { 58 | g_testidx = 4; 59 | } else if (str_isequal_nocase(cmd->arg, "taskmgr")) { 60 | g_testidx = 5; 61 | } else if (str_isequal_nocase(cmd->arg, "hashtable")) { 62 | g_testidx = 6; 63 | } 64 | } 65 | 66 | int show_help() 67 | { 68 | printf("Choose unit test: \n"); 69 | uint test_cnt = sizeof(g_tests)/sizeof(struct unit_test_desc); 70 | 71 | for (uint i = 0; i < test_cnt; i++) { 72 | printf("%d- %s (%s)\n", i, g_tests[i].desc, g_tests[i].name); 73 | } 74 | printf("q- quit\n"); 75 | 76 | char r = util_getch(); 77 | if (r == 'q') { 78 | return -1; 79 | } else if (r >= '0' && r <= '9') { 80 | char rs[2]; 81 | rs[0] = (char)r; 82 | rs[1] = 0; 83 | return atoi(rs); 84 | } else { 85 | return -1; 86 | } 87 | } 88 | 89 | int parse_cmd(const char* arg) 90 | { 91 | uint test_cnt = sizeof(g_tests)/sizeof(struct unit_test_desc); 92 | for (uint i = 0; i < test_cnt; i++) { 93 | if (str_isequal_nocase(arg, g_tests[i].name)) { 94 | return i; 95 | } 96 | } 97 | return -1; 98 | } 99 | 100 | int main(int argc, char** argv) 101 | { 102 | command_t cmd; 103 | command_init(&cmd, "dhcore-test", "1.0"); 104 | command_option_pos(&cmd, "test", "Choose unit test", TRUE, cmd_gettest); 105 | command_parse(&cmd, argc, argv, NULL); 106 | 107 | if (IS_FAIL(core_init(CORE_INIT_ALL))) { 108 | printf("core init error.\n"); 109 | return -1; 110 | } 111 | 112 | log_outputconsole(TRUE); 113 | 114 | if (g_testidx == -1) 115 | g_testidx = show_help(); 116 | 117 | if (g_testidx != -1) 118 | g_tests[g_testidx].test_fn(); 119 | 120 | #if defined(_DEBUG_) 121 | core_release(TRUE); 122 | #else 123 | core_release(FALSE); 124 | #endif 125 | return 1; 126 | } 127 | -------------------------------------------------------------------------------- /src/core/core.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = lib 2 | CONFIG += shared 3 | CONFIG -= app_bundle 4 | CONFIG -= qt 5 | CONFIG -= warn_on 6 | VERSION = "1.0.0" 7 | 8 | DEFINES += _VERSION_=\\\"$$VERSION\\\" 9 | 10 | CONFIG(release, debug|release):TARGET = dhcore 11 | CONFIG(debug, debug|release):TARGET = dhcore-dbg 12 | 13 | INCLUDEPATH = \ 14 | ../../include \ 15 | deps 16 | 17 | DEFINES += _CORE_EXPORT_ 18 | 19 | CONFIG(x86_64): DEFINES += _SIMD_SSE_ 20 | 21 | linux-g++|linux-clang|macx-clang { 22 | QMAKE_CFLAGS += \ 23 | -std=gnu99 \ 24 | -msse -msse2 \ 25 | -ffast-math 26 | QMAKE_CXXFLAGS += \ 27 | -msse -msse2 \ 28 | -ffast-math 29 | LIBS *= -lpthread -lm 30 | } 31 | 32 | win32-msvc2013 | win32-msvc2012 | win32-msvc2010 { 33 | QMAKE_CFLAGS += /TP 34 | 35 | DEFINES += _CRT_SECURE_NO_WARNINGS _WINDOWS _WINDLL _MBCS 36 | DEFINES -= UNICODE 37 | 38 | LIBS += -lws2_32 -lShlwapi -luser32 -lgdi32 -lkernel32 -lAdvapi32 -lShell32 39 | } 40 | 41 | SOURCES += \ 42 | array.c \ 43 | core.c \ 44 | errors.c \ 45 | file-io.c \ 46 | freelist-alloc.c \ 47 | hash.c \ 48 | hash-table.c \ 49 | hwinfo.c \ 50 | json.c \ 51 | log.c \ 52 | mem-mgr.c \ 53 | net-socket.c \ 54 | numeric.c \ 55 | pak-file.c \ 56 | pool-alloc.c \ 57 | prims.c \ 58 | rpc.c \ 59 | stack-alloc.c \ 60 | std-math.c \ 61 | str.c \ 62 | task-mgr.c \ 63 | timer.c \ 64 | util.c \ 65 | variant.c \ 66 | vec-math.c \ 67 | zip.c \ 68 | deps/cJSON/cJSON.c \ 69 | deps/commander/commander.c \ 70 | deps/miniz/miniz.c \ 71 | path.c \ 72 | static-vars.cpp 73 | 74 | # posix 75 | unix { 76 | SOURCES += \ 77 | platform/posix/crash-posix.c \ 78 | platform/posix/mt-posix.c \ 79 | platform/posix/util-posix.c 80 | } 81 | 82 | # windows 83 | win32 { 84 | SOURCES += \ 85 | platform/win/hwinfo-win.c \ 86 | platform/win/mt-win.c \ 87 | platform/win/timer-win.c \ 88 | platform/win/util-win.c \ 89 | platform/win/crash-win.cpp 90 | } 91 | 92 | # mac 93 | macx { 94 | SOURCES += \ 95 | platform/osx/hwinfo-osx.c \ 96 | platform/osx/timer-osx.c \ 97 | platform/osx/util-osx.c 98 | } 99 | 100 | # linux 101 | unix:!macx { 102 | SOURCES += \ 103 | platform/linux/hwinfo-lnx.c \ 104 | platform/linux/timer-lnx.c \ 105 | platform/linux/util-lnx.c 106 | DEFINES += HAVE_MALLOC_H 107 | } 108 | 109 | # debug 110 | CONFIG(debug, debug|release): DEFINES += _DEBUG_ 111 | 112 | HEADERS = \ 113 | ../../include/dhcore/allocator.h \ 114 | ../../include/dhcore/array.h \ 115 | ../../include/dhcore/color.h \ 116 | ../../include/dhcore/commander.h \ 117 | ../../include/dhcore/core-api.h \ 118 | ../../include/dhcore/core.h \ 119 | ../../include/dhcore/crash.h \ 120 | ../../include/dhcore/err.h \ 121 | ../../include/dhcore/error-codes.h \ 122 | ../../include/dhcore/file-io.h \ 123 | ../../include/dhcore/freelist-alloc.h \ 124 | ../../include/dhcore/hash-table.h \ 125 | ../../include/dhcore/hash.h \ 126 | ../../include/dhcore/hwinfo.h \ 127 | ../../include/dhcore/json.h \ 128 | ../../include/dhcore/linked-list.h \ 129 | ../../include/dhcore/log.h \ 130 | ../../include/dhcore/mem-mgr.h \ 131 | ../../include/dhcore/mt.h \ 132 | ../../include/dhcore/net-socket.h \ 133 | ../../include/dhcore/numeric.h \ 134 | ../../include/dhcore/pak-file-fmt.h \ 135 | ../../include/dhcore/pak-file.h \ 136 | ../../include/dhcore/pool-alloc.h \ 137 | ../../include/dhcore/prims.h \ 138 | ../../include/dhcore/queue.h \ 139 | ../../include/dhcore/rpc.h \ 140 | ../../include/dhcore/stack-alloc.h \ 141 | ../../include/dhcore/stack.h \ 142 | ../../include/dhcore/std-math.h \ 143 | ../../include/dhcore/str.h \ 144 | ../../include/dhcore/task-mgr.h \ 145 | ../../include/dhcore/timer.h \ 146 | ../../include/dhcore/types.h \ 147 | ../../include/dhcore/util.h \ 148 | ../../include/dhcore/variant.h \ 149 | ../../include/dhcore/vec-math.h \ 150 | ../../include/dhcore/win.h \ 151 | ../../include/dhcore/zip.h \ 152 | ../../include/dhcore/path.h 153 | 154 | -------------------------------------------------------------------------------- /src/core/platform/posix/crash-posix.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2013, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/crash.h" 17 | 18 | #ifndef _MOBILE_ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "dhcore/log.h" 30 | 31 | /* */ 32 | static pfn_crash_handler g_crash_fn = NULL; 33 | 34 | /*************************************************************************************************/ 35 | int detect_gdb(void) 36 | { 37 | int rc = 0; 38 | FILE *fd = fopen("/tmp", "r"); 39 | 40 | if (fileno(fd) > 5) 41 | rc = 1; 42 | 43 | fclose(fd); 44 | return rc; 45 | } 46 | 47 | void crash_print(const char* text) 48 | { 49 | char* str = (char*)malloc(strlen(text)+5); 50 | strcpy(str+4, text); 51 | str[0] = 32; 52 | str[1] = 32; 53 | str[2] = 32; 54 | str[3] = 32; 55 | 56 | if (!log_isconsole()) 57 | puts(text); 58 | log_print(LOG_INFO, str); 59 | 60 | free(str); 61 | } 62 | 63 | void crash_print_callstack(uint max_frames) 64 | { 65 | /* storage array for stack trace address data */ 66 | void* addrlist[max_frames+1]; 67 | 68 | /* retrieve current stack addresses */ 69 | uint addrlen = backtrace( addrlist, (int)(sizeof(addrlist)/sizeof(void*))); 70 | 71 | if (addrlen == 0) { 72 | crash_print(""); 73 | return; 74 | } 75 | 76 | /* create readable strings to each frame. */ 77 | char** symbollist = backtrace_symbols( addrlist, addrlen ); 78 | 79 | /* print the stack trace. */ 80 | for (uint i = 4; i < addrlen; i++) 81 | crash_print(symbollist[i]); 82 | 83 | free(symbollist); 84 | } 85 | 86 | void crash_handler(int signum) 87 | { 88 | const char* name; 89 | switch (signum) { 90 | case SIGABRT: 91 | name = "SIGABRT (Program abort)"; 92 | break; 93 | case SIGSEGV: 94 | name = "SIGSEGV (Memory access)"; 95 | break; 96 | case SIGILL: 97 | name = "SIGILL (Illegal call)"; 98 | break; 99 | case SIGFPE: 100 | name = "SIGFPE (Illegal FPU call)"; 101 | break; 102 | default: 103 | name = "[unknown]"; 104 | } 105 | 106 | if (!log_isconsole()) { 107 | printf("Fatal Error: %s\n", name); 108 | puts("Callstack:"); 109 | } 110 | 111 | log_printf(LOG_ERROR, "Fatal error: %s", name); 112 | log_print(LOG_TEXT, "Callstack:"); 113 | 114 | crash_print_callstack(63); 115 | 116 | if (g_crash_fn != NULL) { 117 | pfn_crash_handler crash_fn = g_crash_fn; 118 | g_crash_fn = NULL; 119 | crash_fn(); 120 | } 121 | 122 | exit(signum); 123 | } 124 | 125 | result_t crash_init(pfn_crash_handler crash_fn) 126 | { 127 | if (!detect_gdb()) { 128 | signal(SIGABRT, crash_handler); 129 | signal(SIGSEGV, crash_handler); 130 | signal(SIGILL, crash_handler); 131 | signal(SIGFPE, crash_handler); 132 | } 133 | 134 | g_crash_fn = crash_fn; 135 | return RET_OK; 136 | } 137 | 138 | void crash_set_handler(pfn_crash_handler crash_fn) 139 | { 140 | g_crash_fn = crash_fn; 141 | } 142 | #else 143 | result_t crash_init() 144 | { 145 | return RET_OK; 146 | } 147 | 148 | void crash_set_handler(pfn_crash_handler crash_fn) 149 | { 150 | } 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /include/dhcore/queue.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef __QUEUE_H__ 17 | #define __QUEUE_H__ 18 | 19 | #include "types.h" 20 | 21 | /** 22 | * @defgroup queue Queue 23 | * FIFO (first-in-first-out) queue structure \n 24 | * Example usage: \n 25 | * @code 26 | * // queue must be wrapped inside your own structures/objects 27 | * struct myobj 28 | * { 29 | * int data; 30 | * struct queue node; 31 | * }; 32 | * 33 | * // we hold the master queue (pointer) to keep track of the queue 34 | * struct queue* root = NULL; 35 | * 36 | * struct myobj qobj1; 37 | * struct myobj qobj2; 38 | * memset(&qobj1, 0x00, sizeof(qobj1)); 39 | * memset(&qobj2, 0x00, sizeof(qobj2)); 40 | * 41 | * qobj1.data = 1; 42 | * qobj2.data = 2; 43 | * 44 | * queue_push(&root, &qobj1.node, &qobj1); 45 | * queue_push(&root, &qobj2.node, &qobj2); 46 | * 47 | * // ... 48 | * // pop from queue 49 | * struct queue* qitem; 50 | * while ((qitem = queue_pop(&root)) != NULL) { 51 | * struct myobj* obj = qitem->data; 52 | * printf("data: %d\n", obj->data); 53 | * } 54 | * @endcode 55 | * @see queue_push 56 | * @see queue_pop 57 | * @ingroup queue 58 | */ 59 | 60 | struct queue 61 | { 62 | struct queue* next; 63 | void* data; 64 | 65 | #ifdef __cplusplus 66 | queue() : next(NULL), data(NULL) {} 67 | #endif 68 | }; 69 | 70 | /** 71 | * Push an item into queue 72 | * @param pqueue pointer to the root queue (can be NULL) 73 | * @param item queue item to push 74 | * @param data pointer to owner of the 'item' 75 | * @ingroup queue 76 | */ 77 | INLINE void queue_push(struct queue** pqueue, struct queue* item, void* data) 78 | { 79 | if (*pqueue != NULL) { 80 | struct queue* last = *pqueue; 81 | while (last->next != NULL) 82 | last = last->next; 83 | last->next = item; 84 | } else { 85 | *pqueue = item; 86 | } 87 | item->next = NULL; 88 | item->data = data; 89 | } 90 | 91 | /** 92 | * Pops an item from queue 93 | * @param pqueue pointer to the root queue item, if the last item is removed *plist will be NULL 94 | * @return popped queue item, check it's ->data for owner data 95 | * @ingroup queue 96 | */ 97 | INLINE struct queue* queue_pop(struct queue** pqueue) 98 | { 99 | struct queue* item = *pqueue; 100 | if (*pqueue != NULL) { 101 | *pqueue = (*pqueue)->next; 102 | item->next = NULL; 103 | } 104 | return item; 105 | } 106 | 107 | #ifdef __cplusplus 108 | namespace dh { 109 | 110 | // _T: container type for queue's data 111 | template 112 | class Queue 113 | { 114 | private: 115 | Queue<_T> *m_next = nullptr; 116 | _T m_data; 117 | 118 | public: 119 | Queue() = default; 120 | _T data() const { return m_data; } 121 | Queue<_T>* next() const { return m_next; } 122 | 123 | public: 124 | static void push(Queue<_T> **pqueue, Queue<_T> *new_item, _T data) 125 | { 126 | if (*pqueue) { 127 | Queue<_T> *last = *pqueue; 128 | while (last->m_next) 129 | last = last->m_next; 130 | last->m_next = new_item; 131 | } else { 132 | *pqueue = new_item; 133 | } 134 | new_item->m_next = nullptr; 135 | new_item->m_data = data; 136 | } 137 | 138 | static Queue<_T>* pop(Queue<_T> **pqueue) 139 | { 140 | Queue<_T> *item = *pqueue; 141 | if (*pqueue) { 142 | *pqueue = (*pqueue)->m_next; 143 | item->m_next = nullptr; 144 | } 145 | return item; 146 | } 147 | }; 148 | 149 | } 150 | #endif 151 | 152 | #endif /* __QUEUE_H__ */ 153 | -------------------------------------------------------------------------------- /include/dhcore/pool-alloc.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | 17 | #ifndef __POOLALLOC_H__ 18 | #define __POOLALLOC_H__ 19 | 20 | #include "types.h" 21 | #include "linked-list.h" 22 | #include "allocator.h" 23 | #include "core-api.h" 24 | 25 | /** 26 | * Pool allocator: fixed-size pool allocation\n 27 | * it is pretty fast and can dynamically grow itself on demand. but limited to fixed sized blocks\n 28 | * if number of allocations go beyond 'block_size' another block will be created 29 | * @see mem_pool_create 30 | * @ingroup alloc 31 | */ 32 | struct pool_alloc 33 | { 34 | struct linked_list* blocks; /* first node of blocks */ 35 | int blocks_cnt; /* count of memory pool blocks */ 36 | struct allocator* alloc; /* allocator for further block allocations */ 37 | int items_max; /* maximum number of items allowed (per block) */ 38 | int item_sz; /* size of the item in bytes */ 39 | uint mem_id; /* memory id of the pool */ 40 | 41 | #ifdef __cplusplus 42 | pool_alloc() 43 | { 44 | blocks = NULL; 45 | blocks_cnt = 0; 46 | alloc = NULL; 47 | mem_id = 0; 48 | items_max = 0; 49 | item_sz = 0; 50 | } 51 | #endif 52 | }; 53 | 54 | /** 55 | * Creates a fixed item size pool and it's buffer 56 | * @param item_size size of each item (bytes) in the pool 57 | * @param block_size number of items in each pool block 58 | * @ingroup alloc 59 | */ 60 | CORE_API result_t mem_pool_create(struct allocator* alloc, 61 | struct pool_alloc* pool, 62 | int item_size, int block_size, uint mem_id); 63 | 64 | /** 65 | * Destroys pool allocator 66 | * @ingroup alloc 67 | */ 68 | CORE_API void mem_pool_destroy(struct pool_alloc* pool); 69 | 70 | /** 71 | * Allocate an item (fixed-size) from the pool 72 | * @ingroup alloc 73 | */ 74 | CORE_API void* mem_pool_alloc(struct pool_alloc* pool); 75 | 76 | /** 77 | * Free an item from the pool 78 | * @ingroup alloc 79 | */ 80 | CORE_API void mem_pool_free(struct pool_alloc* pool, void* ptr); 81 | 82 | /** 83 | * Get memory pool leaks 84 | * @return number of leaks 85 | * @ingroup alloc 86 | */ 87 | CORE_API int mem_pool_getleaks(struct pool_alloc* pool); 88 | 89 | /** 90 | * Clear memory pool 91 | * @ingroup alloc 92 | */ 93 | CORE_API void mem_pool_clear(struct pool_alloc* pool); 94 | 95 | /** 96 | * Pool binding to generic allocator 97 | * @ingroup alloc 98 | */ 99 | CORE_API void mem_pool_bindalloc(struct pool_alloc* pool, struct allocator* alloc); 100 | 101 | 102 | #ifdef __cplusplus 103 | #include "mem-mgr.h" 104 | 105 | namespace dh { 106 | 107 | template 108 | class PoolAlloc 109 | { 110 | private: 111 | pool_alloc m_pool; 112 | 113 | public: 114 | PoolAlloc() 115 | { 116 | } 117 | 118 | result_t create(int block_sz, uint mem_id = 0, allocator *alloc = mem_heap()) 119 | { 120 | return mem_pool_create(alloc, &m_pool, sizeof(T), block_sz, mem_id); 121 | } 122 | 123 | void destroy() 124 | { 125 | mem_pool_destroy(&m_pool); 126 | } 127 | 128 | T* alloc() 129 | { 130 | return static_cast(mem_pool_alloc(&m_pool)); 131 | } 132 | 133 | void free(T *ptr) 134 | { 135 | mem_pool_free(&m_pool, ptr); 136 | } 137 | 138 | void clear() 139 | { 140 | mem_pool_clear(&m_pool); 141 | } 142 | 143 | void bindto(allocator *alloc) 144 | { 145 | mem_pool_bindalloc(&m_pool, alloc); 146 | } 147 | 148 | int leaks() 149 | { 150 | return mem_pool_getleaks(&m_pool); 151 | } 152 | }; 153 | 154 | } /* dh */ 155 | #endif 156 | 157 | #endif /* __POOLALLOC_H__ */ 158 | -------------------------------------------------------------------------------- /include/dhcore/err.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | /** 17 | * @defgroup err Error handling 18 | * When calling internal functions, many of them will return 'result_t' type.\n 19 | * if error occurs within any function within engine, an error-stack will be created and result_t 20 | * will not return RET_OK, or in case of pointer returns, it will be NULL\n 21 | * To check if result_t is an error, use **IS_FAIL(r)** or **IS_OK(r)** macros.\n 22 | * Example:\n @code 23 | * int my_function() { 24 | * result_t r = some_engine_func(); 25 | * if (IS_FAIL(r)) { 26 | * err_print(__FILE__, __LINE__, "Error occured"); 27 | * return FALSE; 28 | * } 29 | * return TRUE; 30 | * } 31 | * 32 | * void parent_function() { 33 | * if (IS_FAIL(my_function())) { 34 | * // send error to terminal and exit 35 | * printf("Error: %s\n", err_getstring()); 36 | * exit(-1); 37 | * } 38 | * } 39 | * @endcode 40 | */ 41 | 42 | #ifndef __ERR_H__ 43 | #define __ERR_H__ 44 | 45 | #include "types.h" 46 | #include "core-api.h" 47 | 48 | // Enable assert in debug mode anyway 49 | #ifndef _ENABLEASSERT_ 50 | #ifdef _DEBUG_ 51 | #define _ENABLEASSERT_ 52 | #endif 53 | #endif 54 | 55 | #if defined(_ENABLEASSERT_) 56 | #if defined(ASSERT) 57 | #undef ASSERT 58 | #endif 59 | 60 | #if defined(_MSVC_) 61 | #define DEBUG_BREAK() __debugbreak(); 62 | #elif defined(_GNUC_) 63 | #define DEBUG_BREAK() __builtin_trap(); 64 | #endif 65 | 66 | #define ASSERT(expr) \ 67 | if (!(expr)) { err_reportassert(#expr, __FILE__, __LINE__); DEBUG_BREAK(); } 68 | #else 69 | #define ASSERT(expr) 70 | #endif 71 | 72 | /* Assertion */ 73 | CORE_API void err_reportassert(const char* expr, const char* source, uint line); 74 | 75 | /* */ 76 | result_t err_init(); 77 | void err_release(); 78 | 79 | /** 80 | * Print formatted and add item to error-stack 81 | * @param source source file of error occurance 82 | * @param line line of error occurance 83 | * @param fmt formatted string 84 | * @ingroup err 85 | */ 86 | CORE_API void err_printf(const char* source, uint line, const char* fmt, ...); 87 | 88 | /** 89 | * Print text and add item to error-stack 90 | * @param source source file of error occurance 91 | * @param line line of error occurance 92 | * @param text error string 93 | * @ingroup err 94 | */ 95 | CORE_API void err_print(const char* source, uint line, const char* text); 96 | 97 | /** 98 | * Print common error code descriptions to the error-stack 99 | * @param source source file of error occurance 100 | * @param line line of error occurance 101 | * @param err_code error code, usually is casted from result_t 102 | * @ingroup err 103 | */ 104 | CORE_API result_t err_printn(const char* source, uint line, uint err_code); 105 | 106 | /** 107 | * Returns last error code, and **does not clear** error-stack 108 | * @ingroup err 109 | */ 110 | CORE_API uint err_getcode(); 111 | 112 | /** 113 | * Sends error descriptions and call-stack to logger, **clears** the error-stack after call 114 | * @param as_warning send error as warning 115 | * @ingroup err 116 | */ 117 | CORE_API void err_sendtolog(int as_warning); 118 | 119 | /** 120 | * Returns error descriptions and call-stack to the caller, **clears** the error-stack after call 121 | * @return string buffer 122 | * @see err_sendtolog @ingroup err 123 | */ 124 | CORE_API const char* err_getstring(); 125 | /** 126 | * Clears error-stack without output to anything 127 | * @see err_sendtolog @see err_getstring @ingroup err 128 | */ 129 | CORE_API void err_clear(); 130 | 131 | /** 132 | * Checks if we have errors in the error-stack @ingroup err 133 | */ 134 | CORE_API int err_haserrors(); 135 | 136 | #endif /* __ERR_H__ */ 137 | -------------------------------------------------------------------------------- /xcode/dhcore/dhcore.xcodeproj/xcuserdata/Sepul.xcuserdatad/xcschemes/dhcore_ios.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /include/dhcore/pak-file.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | 17 | #ifndef __PAKFILE_H__ 18 | #define __PAKFILE_H__ 19 | 20 | #include 21 | #include "types.h" 22 | #include "core-api.h" 23 | #include "allocator.h" 24 | #include "hash-table.h" 25 | #include "array.h" 26 | #include "pool-alloc.h" 27 | #include "zip.h" 28 | #include "file-io.h" 29 | 30 | /** 31 | * @defgroup pak Pak files 32 | */ 33 | 34 | /* fwd declarations */ 35 | struct file_mgr; 36 | 37 | /** 38 | * pak file - contains zipped archive of multiple files\n 39 | * used in file-mgr for compression and fast extraction of files\n 40 | * @see fileio 41 | * 42 | */ 43 | struct pak_file 44 | { 45 | FILE *f; 46 | struct hashtable_open table; /* hash-table for referencing pak files */ 47 | struct array items; /* file items in the pak (see pak-file.c) */ 48 | enum compress_mode compress_mode; /* compression mode (see zip.h) */ 49 | int init_create; 50 | struct allocator table_alloc; 51 | }; 52 | 53 | /** 54 | * Create pak file on disk and get it ready for putting files in it 55 | * @param alloc memory allocator for internal pak_file data 56 | * @param pakfilepath pak file which will be created on disk (absolute path) 57 | * @param mode zip compression mode 58 | * @see zip 59 | * @ingroup pak 60 | */ 61 | CORE_API result_t pak_create(struct pak_file* pak, struct allocator* alloc, const char* pakfilepath, 62 | enum compress_mode mode, uint mem_id); 63 | 64 | /** 65 | * Open pak file from disk, get it ready to fetch files from it 66 | * @param pakfilepath file path of the pak file on disk (absolute path) 67 | * @param alloc allocator for internal pak_file data 68 | * @ingroup pak 69 | */ 70 | CORE_API result_t pak_open(struct pak_file* pak, struct allocator* alloc, const char* pakfilepath, 71 | uint mem_id); 72 | 73 | /** 74 | * Closes pak file and release internal data 75 | * @ingroup pak 76 | */ 77 | CORE_API void pak_close(struct pak_file* pak); 78 | 79 | /** 80 | * Checks if pak file is opened 81 | * @ingroup pak 82 | */ 83 | CORE_API int pak_isopen(struct pak_file* pak); 84 | 85 | /** 86 | * Compress and put an opened file into pak 87 | * @param alloc temp-allocator for decompressing buffers inside the routine 88 | * @param src_file source file which must be already opened 89 | * @param dest_path destination filepath (alias) which will be saved in pak file_id, future fetches 90 | * from PAK, should provide this path value 91 | * @ingroup pak 92 | */ 93 | CORE_API result_t pak_putfile(struct pak_file* pak, struct allocator* tmp_alloc, 94 | file_t src_file, const char* dest_path); 95 | 96 | /** 97 | * Find a file in pak 98 | * @param filepath filepath (case sensitive) of dest_path provided in 'pak_putfile' when - 99 | * archive was created. 100 | * @return id of the file. 0 if file is not found. 101 | * @ingroup pak 102 | */ 103 | CORE_API uint pak_findfile(struct pak_file* pak, const char* filepath); 104 | 105 | /** 106 | * Decompress and get a file from pak 107 | * @param alloc memory allocator for creating memory file 108 | * @param tmp_alloc temp-allocator for internal memory allocation 109 | * @param file_id file-id of the file in the pak, must be fetched from 'pak_findfile' 110 | * @return handle to the opened file in memory, ready to read 111 | * @ingroup pak 112 | */ 113 | CORE_API file_t pak_getfile(struct pak_file* pak, struct allocator* alloc, 114 | struct allocator* tmp_alloc, uint file_id, uint mem_id); 115 | 116 | /** 117 | * Creates/allocates list of files inside pak-file 118 | * @param alloc memory allocator for the list 119 | * @param pcnt outputs file count 120 | * @return array of char* which contains list of files (should be freed if not needed by caller)\n 121 | * for striding the char** array you should use DH_PATH_MAX strides (char* + index*DH_PATH_MAX) 122 | * @ingroup pak 123 | */ 124 | CORE_API char* pak_createfilelist(struct pak_file* pak, struct allocator* alloc, OUT int* pcnt); 125 | 126 | #endif /*__PAKFILE_H__*/ 127 | -------------------------------------------------------------------------------- /include/dhcore/hash.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | /******************************************************************* 17 | * Hashing Routines 18 | * Murmur3 Hash: http://code.google.com/p/smhasher/ 19 | * Note: Dissed other hashes, because murmur seems to beat them all 20 | * Seed parameter in murmur hash functions are for variation 21 | * you should always provide fixed seed values to get same result 22 | ********************************************************************/ 23 | 24 | #ifndef __HASH_H__ 25 | #define __HASH_H__ 26 | 27 | #include "types.h" 28 | #include "core-api.h" 29 | 30 | /** 31 | * @defgroup hash Hashing functions 32 | */ 33 | 34 | #ifdef _ARCH64_ 35 | typedef struct hash_s 36 | { 37 | uint64 h[2]; 38 | } hash_t; 39 | #else 40 | typedef struct hash_s 41 | { 42 | uint h[4]; 43 | } hash_t; 44 | #endif 45 | 46 | /** 47 | * Incremental hash structure 48 | * @see hash_murmurincr_begin @ingroup hash 49 | */ 50 | struct hash_incr 51 | { 52 | uint hash; 53 | uint tail; 54 | uint cnt; 55 | size_t size; 56 | }; 57 | 58 | /** 59 | * Test for 128bit hash equality 60 | * @ingroup hash 61 | */ 62 | INLINE int hash_isequal(hash_t h1, hash_t h2); 63 | 64 | #ifdef _ARCH64_ 65 | INLINE int hash_isequal(hash_t h1, hash_t h2) 66 | { 67 | return (h1.h[0] == h2.h[0] && h1.h[1] == h2.h[1]); 68 | } 69 | 70 | INLINE void hash_set(hash_t* dest, hash_t src) 71 | { 72 | dest->h[0] = src.h[0]; 73 | dest->h[1] = src.h[1]; 74 | } 75 | 76 | INLINE void hash_zero(hash_t* h) 77 | { 78 | h->h[0] = 0; 79 | h->h[1] = 0; 80 | } 81 | 82 | #else 83 | INLINE int hash_isequal(hash_t h1, hash_t h2) 84 | { 85 | 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]); 86 | } 87 | 88 | INLINE void hash_set(hash_t* dest, hash_t src) 89 | { 90 | dest->h[0] = src.h[0]; 91 | dest->h[1] = src.h[1]; 92 | dest->h[2] = src.h[2]; 93 | dest->h[3] = src.h[3]; 94 | } 95 | 96 | INLINE void hash_zero(hash_t* h) 97 | { 98 | h->h[0] = 0; h->h[1] = 0; 99 | h->h[2] = 0; h->h[3] = 0; 100 | } 101 | #endif 102 | 103 | 104 | /** 105 | * murmur 32bit hash 106 | * @param key buffer containing data to be hashed 107 | * @param size_bytes size of buffer (bytes) 108 | * @param seed random seed value (must be same between hashes in order to compare 109 | * @return 32bit hash value 110 | * @ingroup hash 111 | */ 112 | CORE_API uint hash_murmur32(const void* key, size_t size_bytes, uint seed); 113 | 114 | /** 115 | * murmur 128bit hash 116 | * @param key buffer containing data to be hashed 117 | * @param size_bytes size of buffer (bytes) 118 | * @param seed random seed value (must be same between hashes in order to compare 119 | * @return 128bit hash value 120 | * @ingroup hash 121 | */ 122 | CORE_API hash_t hash_murmur128(const void* key, size_t size_bytes, uint seed); 123 | 124 | /** 125 | * hash 64bit value to 32bit 126 | * @param n 64bit value to be hashed 127 | * @return 32bit hash value 128 | * @ingroup hash 129 | */ 130 | CORE_API uint hash_u64(uint64 n); 131 | 132 | /** 133 | * hash 32bit value to 16bit 134 | * @param n 32bit value to be hashed 135 | * @return 16bit hash value 136 | * @ingroup hash 137 | */ 138 | CORE_API uint16 hash_u32(uint n); 139 | 140 | /** 141 | * incremental hashing, based on murmur2A\n 142 | * begins incremental hashing, user must call _add and _end functions after _begin\n 143 | * @see hash_murmurincr_add @see hash_murmurincr_end 144 | * @ingroup hash 145 | */ 146 | CORE_API void hash_murmurincr_begin(struct hash_incr* h, uint seed); 147 | 148 | /** 149 | * incremental hash addition 150 | * @see hash_murmurincr_begin 151 | * @ingroup hash 152 | */ 153 | CORE_API void hash_murmurincr_add(struct hash_incr* h, const void* data, size_t size); 154 | 155 | /** 156 | * incremental hash end 157 | * @return 32bit hash value 158 | * @see hash_murmurincr_begin 159 | * @ingroup hash 160 | */ 161 | CORE_API uint hash_murmurincr_end(struct hash_incr* h); 162 | 163 | /** 164 | * Hashes a null-terminated string to 32-bit integer 165 | * @ingroup hash 166 | */ 167 | CORE_API uint hash_str(const char* str); 168 | 169 | 170 | #endif 171 | -------------------------------------------------------------------------------- /src/core/platform/posix/util-posix.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/util.h" 17 | 18 | #if defined(_POSIXLIB_) 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #if defined(_LINUX_) 32 | #include 33 | #elif defined(_APPLE_) 34 | #include 35 | #include 36 | #include 37 | #endif 38 | 39 | #include "dhcore/mem-mgr.h" 40 | #include "dhcore/str.h" 41 | #include "dhcore/path.h" 42 | 43 | char* util_runcmd(const char* cmd) 44 | { 45 | char buff[4096]; 46 | char* ret = NULL; 47 | FILE* f = popen(cmd, "r"); 48 | if (f == NULL) 49 | return NULL; 50 | 51 | size_t offset = 0; 52 | fseek(f, 0, SEEK_END); 53 | while (!feof(f)) { 54 | size_t rb = fread(buff, sizeof(char), sizeof(buff), f); 55 | if (ret != NULL) { 56 | char* tmp = ret; 57 | ret = ALLOC(rb + offset, 0); 58 | memcpy(ret, tmp, offset); 59 | FREE(tmp); 60 | } else { 61 | ret = ALLOC(rb, 0); 62 | } 63 | memcpy(ret + offset, buff, rb); 64 | offset += rb; 65 | } 66 | pclose(f); 67 | return ret; 68 | } 69 | 70 | char util_getch() 71 | { 72 | int ch; 73 | struct termios oldt, newt; 74 | tcgetattr(STDIN_FILENO, &oldt); 75 | newt = oldt; 76 | newt.c_lflag &= ~(ICANON | ECHO); 77 | newt.c_cc[VMIN] = 1; 78 | newt.c_cc[VTIME] = 0; 79 | 80 | tcsetattr(STDIN_FILENO, TCSANOW, &newt); 81 | ch = getchar(); 82 | tcsetattr(STDIN_FILENO, TCSANOW, &oldt); 83 | return ch; 84 | } 85 | 86 | void util_ttyecho() 87 | { 88 | struct termios t; 89 | tcgetattr(STDIN_FILENO, &t); 90 | t.c_lflag |= ECHO; 91 | tcsetattr(STDIN_FILENO, TCSANOW, &t); 92 | } 93 | 94 | #if defined(_IOS_) 95 | char* util_getconfdir(char* outdir) 96 | { 97 | return path_join(outdir, "Library", "Application Support", NULL); 98 | } 99 | 100 | char* util_getuserdir(char* outdir) 101 | { 102 | outdir[0] = 0; 103 | return outdir; 104 | } 105 | 106 | char* util_gettempdir(char* outdir) 107 | { 108 | return strcpy(outdir, "tmp"); 109 | } 110 | #else 111 | char* util_getconfdir(char* outdir) 112 | { 113 | return path_join(outdir, util_getuserdir(outdir), ".config", NULL); 114 | } 115 | 116 | char* util_getuserdir(char* outdir) 117 | { 118 | struct passwd* pw = getpwuid(getuid()); 119 | return strcpy(outdir, pw->pw_dir); 120 | } 121 | 122 | char* util_gettempdir(char* outdir) 123 | { 124 | return strcpy(outdir, "/tmp"); 125 | } 126 | #endif 127 | 128 | int util_makedir(const char* dir) 129 | { 130 | return mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0; 131 | } 132 | 133 | /* reference: http://stackoverflow.com/questions/2180079/how-can-i-copy-a-file-on-unix-using-c */ 134 | int util_copyfile(const char* dest, const char* src) 135 | { 136 | int input, output; 137 | if ((input = open(src, O_RDONLY)) == -1) 138 | return FALSE; 139 | 140 | if ((output = open(dest, O_WRONLY | O_CREAT, O_NOFOLLOW)) == -1) { 141 | close(input); 142 | return FALSE; 143 | } 144 | 145 | #ifdef _LINUX_ 146 | int result = sendfile(output, input, NULL, 0) != -1; 147 | #elif defined(_APPLE_) 148 | off_t bytesCopied; 149 | int result = sendfile(output, input, 0, &bytesCopied, 0, 0) != -1; 150 | #endif 151 | close(input); 152 | close(output); 153 | return result; 154 | } 155 | 156 | int util_pathisdir(const char* path) 157 | { 158 | struct stat s; 159 | if (stat(path, &s) == 0) 160 | return (s.st_mode & S_IFDIR); 161 | else 162 | return FALSE; 163 | } 164 | 165 | void util_sleep(uint msecs) 166 | { 167 | usleep(msecs*1000); 168 | } 169 | 170 | int util_movefile(const char* dest, const char* src) 171 | { 172 | return rename(src, dest) == 0; 173 | } 174 | 175 | int util_delfile(const char* filepath) 176 | { 177 | return unlink(filepath); 178 | } 179 | 180 | #endif /* _POSIX_ */ 181 | -------------------------------------------------------------------------------- /src/core/platform/linux/hwinfo-lnx.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2013, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/hwinfo.h" 17 | 18 | #if defined(_LINUX_) 19 | 20 | #include "dhcore/core.h" 21 | #include 22 | #include 23 | 24 | void query_meminfo(struct hwinfo* info) 25 | { 26 | char* data = util_runcmd("cat /proc/meminfo"); 27 | if (data != NULL) { 28 | char* token = strtok(data, "\n"); 29 | while (token != NULL) { 30 | if (strstr(token, "MemTotal:")) { 31 | str_trim(token, strlen(token), token, " \t"); 32 | info->sys_mem = str_toint32(strchr(token, ':') + 1); 33 | } else if (strstr(token, "Active:")) { 34 | str_trim(token, strlen(token), token, " \t"); 35 | info->sys_memfree = info->sys_mem - str_toint32(strchr(token, ':') + 1); 36 | } 37 | 38 | if (info->sys_mem != 0 && info->sys_memfree != 0) 39 | break; 40 | 41 | token = strtok(NULL, "\n"); 42 | } 43 | FREE(data); 44 | } 45 | } 46 | 47 | void query_cpuinfo(struct hwinfo* info) 48 | { 49 | char* data = util_runcmd("cat /proc/cpuinfo"); 50 | if (data != NULL) { 51 | char* token = strtok(data, "\n"); 52 | while (token != NULL) { 53 | /* vendor */ 54 | if (strstr(token, "vendor_id")) { 55 | if (strstr(token, "GenuineIntel")) 56 | info->cpu_type = HWINFO_CPU_INTEL; 57 | else if (strstr(token, "AuthenticAMD")) 58 | info->cpu_type = HWINFO_CPU_AMD; 59 | else 60 | info->cpu_type = HWINFO_CPU_UNKNOWN; 61 | } 62 | 63 | /* cpu name */ 64 | else if (strstr(token, "model name")) { 65 | if (!str_isempty(info->cpu_name)) 66 | break; 67 | strcpy(info->cpu_name, strchr(token, ':') + 2); 68 | } 69 | 70 | /* cpu features */ 71 | else if (strstr(token, "flags")) { 72 | if (strstr(token, "mmx ")) { 73 | BIT_ADD(info->cpu_caps, HWINFO_CPUEXT_MMX); 74 | strcat(info->cpu_feat, "MMX "); 75 | } 76 | if (strstr(token, "sse ")) { 77 | BIT_ADD(info->cpu_caps, HWINFO_CPUEXT_SSE); 78 | strcat(info->cpu_feat, "SSE "); 79 | } 80 | if (strstr(token, "sse2")) { 81 | BIT_ADD(info->cpu_caps, HWINFO_CPUEXT_SSE2); 82 | strcat(info->cpu_feat, "SSE2 "); 83 | } 84 | if (strstr(token, "sse3")) { 85 | BIT_ADD(info->cpu_caps, HWINFO_CPUEXT_SSE3); 86 | strcat(info->cpu_feat, "SSE3 "); 87 | } 88 | if (strstr(token, "sse4")) { 89 | BIT_ADD(info->cpu_caps, HWINFO_CPUEXT_SSE4); 90 | strcat(info->cpu_feat, "SSE4 "); 91 | } 92 | } 93 | 94 | /* clock speed */ 95 | else if (strstr(token, "cpu MHz")) { 96 | info->cpu_clock = str_toint32(strchr(token, ':') + 2); 97 | } 98 | 99 | /* cache */ 100 | else if (strstr(token, "cache size")) { 101 | info->cpu_cachesize = str_toint32(strchr(token, ':') + 2); 102 | } 103 | 104 | /* cache line */ 105 | else if (strstr(token, "cache_alignment")) { 106 | info->cpu_cacheline = str_toint32(strchr(token, ':') + 2); 107 | } 108 | 109 | token = strtok(NULL, "\n"); 110 | } 111 | FREE(data); 112 | } 113 | 114 | info->cpu_core_cnt = maxi(sysconf(_SC_NPROCESSORS_ONLN), 1); 115 | info->cpu_pcore_cnt = maxi(info->cpu_pcore_cnt, 1); 116 | } 117 | 118 | void query_osinfo(struct hwinfo* info) 119 | { 120 | struct utsname data; 121 | uname(&data); 122 | info->os_type = HWINFO_OS_LINUX; 123 | sprintf(info->os_name, "%s %s - %s", data.sysname, data.machine, data.release); 124 | } 125 | 126 | uint query_clockspeed(uint cpu_idx) 127 | { 128 | return 0; 129 | } 130 | 131 | #endif /* _LINUX_ */ 132 | -------------------------------------------------------------------------------- /include/dhcore/str.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef __STR_H__ 17 | #define __STR_H__ 18 | 19 | #include "types.h" 20 | #include "core-api.h" 21 | 22 | #if defined(_MSVC_) 23 | #define snprintf _snprintf 24 | #endif 25 | 26 | /** 27 | * @defgroup str Strings 28 | * string utility functions\n 29 | * most string/path functions get output string as paramter and returns result as a const return value\n 30 | * all functions can be operated on single string buffer. example: return path_getfilename(path, path); 31 | * @ingroup str 32 | */ 33 | 34 | /** 35 | * checks equality of two strings - case sensitive 36 | * @ingroup str 37 | */ 38 | CORE_API int str_isequal(const char* str1, const char* str2); 39 | /** 40 | * checks equality of two strings - case insensitive 41 | * @ingroup str 42 | */ 43 | CORE_API int str_isequal_nocase(const char* str1, const char* str2); 44 | /** 45 | * converts integer 'n' to string ('instr') 46 | * @ingroup str 47 | */ 48 | CORE_API char* str_itos(char* instr, int n); 49 | /** 50 | * converts float 'f' to string 51 | * @ingroup str 52 | */ 53 | CORE_API char* str_ftos(char* instr, float f); 54 | /** 55 | * converts boolean 'b' to string 56 | * @ingroup str 57 | */ 58 | CORE_API char* str_btos(char* instr, int b); 59 | /** 60 | * converts string to integer 61 | * @ingroup str 62 | */ 63 | CORE_API int str_toint32(const char* str); 64 | /** 65 | * converts string to float 66 | * @ingroup str 67 | */ 68 | CORE_API float str_tofl32(const char* str); 69 | /** 70 | * converts string to bool, ('false', '0', '') defines FALSE and ('true', '1') defines TRUE 71 | * @ingroup str 72 | */ 73 | CORE_API int str_tobool(const char* str); 74 | /** 75 | * trims string 'instr' from sequence of characters defined by 'trim_chars' 76 | * @param instr input string 77 | * @param trim_chars sequence of characters to be trimmed from input string 78 | * @param outstr output string 79 | * @param outstr_size output string buffer size (including null-terminated char) 80 | * @ingroup str 81 | */ 82 | CORE_API char* str_trim(char* outstr, uint outstr_size, const char* instr, const char* trim_chars); 83 | /** 84 | * replace characters of 'str' with another character 85 | * @param str input string 86 | * @param replace_ch character to be replaced 87 | * @param with_ch new character 88 | * @ingroup str 89 | */ 90 | CORE_API char* str_replace(char* str, char replace_ch, char with_ch); 91 | /** 92 | * convert wide unicode string to multi-byte utf-8 93 | * @ingroup str 94 | */ 95 | CORE_API char* str_widetomb(char* outstr, const wchar* instr, uint outstr_size); 96 | /** 97 | * convert multi-byte utf-8 string to wide unicode 98 | * @ingroup str 99 | */ 100 | CORE_API wchar* str_mbtowide(wchar* outstr, const char* instr, uint outstr_size); 101 | /** 102 | * checks if string is empty (='') 103 | * @ingroup str 104 | */ 105 | INLINE int str_isempty(const char* str) 106 | { 107 | return (str[0] == 0); 108 | } 109 | 110 | /** 111 | * safe copy string (checks size) 112 | * @ingroup str 113 | */ 114 | CORE_API char* str_safecpy(char* outstr, uint outstr_sz, const char* instr); 115 | 116 | /** 117 | * safe cat string (checks size) 118 | * @ingroup str 119 | */ 120 | CORE_API char* str_safecat(char* outstr, uint outstr_sz, const char* instr); 121 | 122 | /** 123 | * encode a normal single-byte string into utf-8 124 | * @ingroup str 125 | */ 126 | CORE_API char* str_utf8_encode(const char* instr, uint instr_len, uint* out_len); 127 | 128 | /** 129 | * decode utf-8 string into single-byte 130 | * @ingroup str 131 | */ 132 | CORE_API char* str_utf8_decode(const char* instr, uint instr_len); 133 | 134 | /** 135 | * free allocated utf-8 string using either @see str_utf8_encode or @see str_utf8_decode 136 | * @ingroup str 137 | */ 138 | CORE_API void str_utf8_free(char* s); 139 | 140 | /** 141 | * convert hex pointer string to actual pointer (ex. 0x014A3BC) 142 | * @ingroup str 143 | */ 144 | CORE_API void* str_toptr(const char* s); 145 | 146 | /** 147 | * @brief Trims white space from the beginning and the end of the string 148 | * @param str Input string, will be modified 149 | * @ingroup str 150 | * @return 151 | */ 152 | CORE_API char* str_trim_whitespace(char *str); 153 | 154 | #endif /*__STR_H__*/ 155 | -------------------------------------------------------------------------------- /src/core/platform/osx/hwinfo-osx.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2013, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | /** 17 | * Author: Davide Bacchet 18 | */ 19 | 20 | #include "dhcore/hwinfo.h" 21 | 22 | #if defined(_APPLE_) 23 | 24 | #include 25 | #include 26 | 27 | #include "dhcore/core.h" 28 | 29 | int get_sys_string(const char *name, char *buf, unsigned int buflen) 30 | { 31 | size_t size = buflen; 32 | if (sysctlbyname(name, buf, &size, NULL, 0) < 0) 33 | return 0; 34 | return 1; 35 | } 36 | 37 | int get_sys_int64(const char *name, int64_t *val) 38 | { 39 | size_t size = sizeof(int64_t); 40 | if (sysctlbyname(name, val, &size, NULL, 0) < 0) 41 | return 0; 42 | return 1; 43 | } 44 | 45 | void query_meminfo(struct hwinfo* info) 46 | { 47 | int mib[2] = { CTL_HW, HW_MEMSIZE }; 48 | u_int namelen = sizeof(mib) / sizeof(mib[0]); 49 | uint64_t mem_size; 50 | size_t len = sizeof(mem_size); 51 | 52 | if (sysctl(mib, namelen, &mem_size, &len, NULL, 0) < 0) { 53 | perror("ERROR: sysctl"); 54 | } 55 | 56 | info->sys_mem = (size_t)mem_size; 57 | info->sys_memfree = 0; ///< \todo implement free memory count on OSX 58 | } 59 | 60 | void query_cpuinfo(struct hwinfo* info) 61 | { 62 | char tmpstr[1024]; 63 | int64_t tmpint64; 64 | /* vendor */ 65 | if (get_sys_string("machdep.cpu.vendor", tmpstr, 1024)) { 66 | if (strstr(tmpstr, "GenuineIntel")) info->cpu_type = HWINFO_CPU_INTEL; 67 | else if (strstr(tmpstr, "AuthenticAMD")) info->cpu_type = HWINFO_CPU_AMD; 68 | else info->cpu_type = HWINFO_CPU_UNKNOWN; 69 | } 70 | /* cpu name */ 71 | if (get_sys_string("machdep.cpu.brand_string", tmpstr, 1024)) 72 | strcpy(info->cpu_name, tmpstr); 73 | /* cpu features */ 74 | if (get_sys_string("machdep.cpu.features", tmpstr, 1024)) { 75 | if (strstr(tmpstr, "MMX ")) { 76 | BIT_ADD(info->cpu_caps, HWINFO_CPUEXT_MMX); 77 | strcat(info->cpu_feat, "MMX "); 78 | } 79 | if (strstr(tmpstr, "SSE ")) { 80 | BIT_ADD(info->cpu_caps, HWINFO_CPUEXT_SSE); 81 | strcat(info->cpu_feat, "SSE "); 82 | } 83 | if (strstr(tmpstr, "SSE2")) { 84 | BIT_ADD(info->cpu_caps, HWINFO_CPUEXT_SSE2); 85 | strcat(info->cpu_feat, "SSE2 "); 86 | } 87 | if (strstr(tmpstr, "SSE3")) { 88 | BIT_ADD(info->cpu_caps, HWINFO_CPUEXT_SSE3); 89 | strcat(info->cpu_feat, "SSE3 "); 90 | } 91 | if (strstr(tmpstr, "SSE4")) { 92 | BIT_ADD(info->cpu_caps, HWINFO_CPUEXT_SSE4); 93 | strcat(info->cpu_feat, "SSE4 "); 94 | } 95 | } 96 | /* clock speed MHz */ 97 | if (get_sys_int64("hw.cpufrequency", &tmpint64)) 98 | info->cpu_clock = (int)((double)tmpint64/1E6); 99 | /* cache size Kb */ 100 | int64_t cachesize = -1; 101 | if (get_sys_int64("hw.l1icachesize", &tmpint64)) 102 | if (tmpint64>cachesize) cachesize = tmpint64; 103 | if (get_sys_int64("hw.l2cachesize", &tmpint64)) 104 | if (tmpint64>cachesize) cachesize = tmpint64; 105 | if (get_sys_int64("hw.l3cachesize", &tmpint64)) 106 | if (tmpint64>cachesize) cachesize = tmpint64; 107 | info->cpu_cachesize = (uint)(cachesize/1024.0); 108 | /* cores */ 109 | if (get_sys_int64("machdep.cpu.core_count", &tmpint64)) 110 | info->cpu_pcore_cnt = (uint)(tmpint64); 111 | if (get_sys_int64("machdep.cpu.thread_count", &tmpint64)) 112 | info->cpu_core_cnt = (uint)(tmpint64); 113 | /* cache line */ 114 | if (get_sys_int64("hw.cachelinesize", &tmpint64)) 115 | info->cpu_cacheline = (uint)(tmpint64); 116 | } 117 | 118 | void query_osinfo(struct hwinfo* info) 119 | { 120 | info->os_type = HWINFO_OS_OSX; 121 | char data_sysname[128]; 122 | char data_sysversion[128]; 123 | get_sys_string("kern.ostype", data_sysname, 128); 124 | get_sys_string("kern.osrelease", data_sysversion, 128); 125 | sprintf(info->os_name, "%s - %s", data_sysname, data_sysversion); 126 | } 127 | 128 | uint query_clockspeed(uint cpu_idx) 129 | { 130 | return 0; 131 | } 132 | 133 | 134 | #endif /* _OSX_ */ 135 | -------------------------------------------------------------------------------- /include/dhcore/timer.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | 17 | #ifndef __TIMER_H__ 18 | #define __TIMER_H__ 19 | 20 | #include "types.h" 21 | #include "linked-list.h" 22 | #include "core-api.h" 23 | #include "pool-alloc.h" 24 | 25 | /** 26 | * @defgroup timer Timers 27 | */ 28 | 29 | /** 30 | * Basic timer structure, holds data for each timer instance 31 | * @ingroup timer 32 | */ 33 | struct timer 34 | { 35 | float t; /**< elapsed time */ 36 | float dt; /**< delta time */ 37 | float rate; /**< playrate, =0.0 stopped, =1.0 normal */ 38 | struct linked_list node; /**< linked-list node */ 39 | }; 40 | 41 | #define TIMER_PAUSE(tm) tm->rate = 0; 42 | #define TIMER_START(tm) tm->rate = 1.0f; 43 | #define TIMER_SCALE(tm, s) tm->rate *= s; 44 | #define TIMER_STOP(tm) tm->rate = 0; tm->t = 0.0f; tm->dt = 0.0f; 45 | 46 | /* */ 47 | result_t timer_initmgr(); 48 | void timer_releasemgr(); 49 | 50 | /** 51 | * Add timers to the timer system \n 52 | * Added timers will be updated only after each call to @e timer_update\n 53 | * To calculate Hi-res timing manually and on-demand, use @e timer_calctm and @e timer_querytick 54 | * functions 55 | * @param start defines if timer should be started immediately after added to the manager 56 | * @see timer_update 57 | * @see timer_destroyinstance 58 | * @see timer_querytick 59 | * @see timer_calctm 60 | * @ingroup timer 61 | */ 62 | CORE_API struct timer* timer_createinstance(int start); 63 | 64 | /** 65 | * Remove timer from timer_mgr\n 66 | * removed timer will no longer be updated 67 | * @ingroup timer 68 | */ 69 | CORE_API void timer_destroyinstance(struct timer* tm); 70 | 71 | /** 72 | * Update all added timers in timer_mgr 73 | * @param tick timer tick of current point in time 74 | * @see timer_querytick 75 | * @ingroup timer 76 | */ 77 | CORE_API void timer_update(uint64 tick); 78 | 79 | /** 80 | * Query cpu tick time, for manual timing calculation. 81 | * @return 64bit Integer tick value, which can be passed to @e timer_calctm for actual time calculation 82 | * @see timer_calctm 83 | * @ingroup timer 84 | */ 85 | CORE_API uint64 timer_querytick(); 86 | 87 | /** 88 | * Calculates the time (in seconds) between two ticks 89 | * @see timer_querytick 90 | * @ingroup timer 91 | */ 92 | CORE_API fl64 timer_calctm(uint64 tick1, uint64 tick2); 93 | 94 | /** 95 | * Pause all timers 96 | * @ingroup timer 97 | */ 98 | CORE_API void timer_pauseall(); 99 | 100 | /** 101 | * Resume all timers 102 | * @ingroup timer 103 | */ 104 | CORE_API void timer_resumeall(); 105 | 106 | #ifdef __cplusplus 107 | 108 | #include "err.h" 109 | 110 | namespace dh { 111 | 112 | class Timer 113 | { 114 | private: 115 | timer *m_tm; 116 | 117 | public: 118 | Timer() : m_tm(NULL) {} 119 | Timer(timer *tm) : m_tm(tm) {} 120 | 121 | static Timer create(bool start = false) 122 | { 123 | return Timer(timer_createinstance(start)); 124 | } 125 | 126 | void destroy() 127 | { 128 | if (m_tm) 129 | timer_destroyinstance(m_tm); 130 | } 131 | 132 | void start(float rate = 1.0f) 133 | { 134 | ASSERT(m_tm); 135 | TIMER_START(m_tm); 136 | m_tm->rate = rate; 137 | } 138 | 139 | void pause() 140 | { 141 | ASSERT(m_tm); 142 | TIMER_PAUSE(m_tm); 143 | } 144 | 145 | void restart(float rate = 1.0f) 146 | { 147 | ASSERT(m_tm); 148 | m_tm->t = 0.0f; 149 | m_tm->dt = 0.0f; 150 | m_tm->rate = rate; 151 | } 152 | 153 | void stop() 154 | { 155 | ASSERT(m_tm); 156 | TIMER_STOP(m_tm); 157 | } 158 | 159 | float delta() const 160 | { 161 | return m_tm->dt; 162 | } 163 | 164 | float t() const 165 | { 166 | return m_tm->t; 167 | } 168 | 169 | float rate() const 170 | { 171 | return m_tm->rate; 172 | } 173 | 174 | void set_rate(float rate) 175 | { 176 | m_tm->rate = rate; 177 | } 178 | }; 179 | 180 | class ProfileTimer 181 | { 182 | private: 183 | uint64 m_t0; 184 | 185 | public: 186 | ProfileTimer() : m_t0(0) {} 187 | 188 | void begin() 189 | { 190 | m_t0 = timer_querytick(); 191 | } 192 | 193 | double end() 194 | { 195 | return timer_calctm(m_t0, timer_querytick()); 196 | } 197 | }; 198 | 199 | } 200 | #endif 201 | 202 | #endif /*__TIMER_H__*/ 203 | 204 | -------------------------------------------------------------------------------- /include/dhcore/freelist-alloc.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef __FREELIST_ALLOC_H__ 17 | #define __FREELIST_ALLOC_H__ 18 | 19 | #include "types.h" 20 | #include "allocator.h" 21 | #include "linked-list.h" 22 | #include "core-api.h" 23 | 24 | /** 25 | * freelist allocator: variable-sized small block memory allocator\n 26 | * more that 8k memory blocks will be allocated from heap 27 | * @ingroup alloc 28 | */ 29 | struct freelist_alloc 30 | { 31 | uint8* buffer; 32 | size_t size; 33 | size_t alloc_size; 34 | struct linked_list* free_chunks; 35 | struct linked_list* alloc_chunks; 36 | struct allocator* alloc; 37 | 38 | #ifdef __cplusplus 39 | freelist_alloc() 40 | { 41 | buffer = NULL; 42 | size = 0; 43 | alloc_size = 0; 44 | free_chunks = NULL; 45 | alloc_chunks = NULL; 46 | alloc = NULL; 47 | } 48 | #endif 49 | }; 50 | 51 | /** 52 | * freelist create/destroy 53 | * @param alloc allocator for internal freelist memory 54 | * @param size size (in bytes) for freelist buffer 55 | * @see mem_freelist_destroy @ingroup alloc 56 | */ 57 | CORE_API result_t mem_freelist_create(struct allocator* alloc, 58 | struct freelist_alloc* freelist, 59 | size_t size, uint mem_id); 60 | /** 61 | * destroy freelist 62 | * @ingroup alloc 63 | */ 64 | CORE_API void mem_freelist_destroy(struct freelist_alloc* freelist); 65 | 66 | /** 67 | * allocate memory from freelist 68 | * @param size size (in bytes) of requested memory, if requested size is more than 8k - 69 | * see (freelist-alloc.c), memory will be allocated from heap instead of freelist 70 | * @return allocated memory block @ingroup alloc 71 | */ 72 | CORE_API void* mem_freelist_alloc(struct freelist_alloc* freelist, size_t size, uint mem_id); 73 | 74 | /** 75 | * Aligned allocation from freelist 76 | * @see mem_freelist_alloc 77 | * @ingroup alloc 78 | */ 79 | CORE_API void* mem_freelist_alignedalloc(struct freelist_alloc* freelist, size_t size, 80 | uint8 alignment, uint mem_id); 81 | 82 | /** 83 | * @ingroup alloc 84 | */ 85 | CORE_API void mem_freelist_free(struct freelist_alloc* freelist, void* ptr); 86 | 87 | /** 88 | * @ingroup alloc 89 | */ 90 | CORE_API void mem_freelist_alignedfree(struct freelist_alloc* freelist, void* ptr); 91 | 92 | /** 93 | * get freelist memory leaks 94 | * @param pptrs array of pointers to the leaks, if =NULL function only returns number of leaks 95 | * @return number of leaks 96 | * @ingroup alloc 97 | */ 98 | CORE_API int mem_freelist_getleaks(struct freelist_alloc* freelist, void** pptrs); 99 | 100 | /** 101 | * get size of the allocated memory from freelist 102 | */ 103 | CORE_API size_t mem_freelist_getsize(struct freelist_alloc* freelist, void* ptr); 104 | 105 | /** 106 | * bind freelist-alloc to generic allocator 107 | * @ingroup alloc 108 | */ 109 | CORE_API void mem_freelist_bindalloc(struct freelist_alloc* freelist, struct allocator* alloc); 110 | 111 | #ifdef __cplusplus 112 | 113 | #include "mem-mgr.h" 114 | 115 | namespace dh { 116 | 117 | class FreelistAlloc 118 | { 119 | private: 120 | freelist_alloc m_fl; 121 | 122 | public: 123 | FreelistAlloc() 124 | { 125 | } 126 | 127 | result_t create(size_t size, uint mem_id = 0, allocator *alloc = mem_heap()) 128 | { 129 | return mem_freelist_create(alloc, &m_fl, size, mem_id); 130 | } 131 | 132 | void destroy() 133 | { 134 | mem_freelist_destroy(&m_fl); 135 | } 136 | 137 | void* alloc(size_t size, uint mem_id = 0) 138 | { 139 | mem_freelist_alloc(&m_fl, size, mem_id); 140 | } 141 | 142 | void free(void *ptr) 143 | { 144 | mem_freelist_free(&m_fl, ptr); 145 | } 146 | 147 | void* alloc_aligned(size_t size, uint8 align = 16, uint mem_id = 0) 148 | { 149 | mem_freelist_alignedalloc(&m_fl, size, align, mem_id); 150 | } 151 | 152 | void free_aligned(void *ptr) 153 | { 154 | mem_freelist_alignedfree(&m_fl, ptr); 155 | } 156 | 157 | void bindto(allocator *alloc) 158 | { 159 | mem_freelist_bindalloc(&m_fl, alloc); 160 | } 161 | 162 | int leaks(void **pptrs = NULL) 163 | { 164 | return mem_freelist_getleaks(&m_fl, pptrs); 165 | } 166 | }; 167 | 168 | } /* dh */ 169 | #endif 170 | 171 | #endif 172 | -------------------------------------------------------------------------------- /src/core/variant.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2013, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include "dhcore/variant.h" 17 | #include "dhcore/str.h" 18 | #include "dhcore/err.h" 19 | 20 | /*************************************************************************************************/ 21 | struct variant* var_setv(struct variant* rv, const struct variant* v) 22 | { 23 | rv->type = v->type; 24 | rv->fv[0] = v->fv[0]; 25 | rv->fv[1] = v->fv[1]; 26 | rv->fv[2] = v->fv[2]; 27 | rv->fv[3] = v->fv[3]; 28 | return rv; 29 | } 30 | 31 | struct variant* var_setb(struct variant* v, int b) 32 | { 33 | v->type = VAR_TYPE_BOOL; 34 | v->b = b; 35 | return v; 36 | } 37 | 38 | struct variant* var_seti(struct variant* v, int i) 39 | { 40 | v->type = VAR_TYPE_INT; 41 | v->i = i; 42 | return v; 43 | } 44 | 45 | struct variant* var_setf(struct variant* v, float f) 46 | { 47 | v->type = VAR_TYPE_FLOAT; 48 | v->f = f; 49 | return v; 50 | } 51 | 52 | struct variant* var_set2fv(struct variant* v, const float* fv) 53 | { 54 | v->type = VAR_TYPE_FLOAT2; 55 | v->fv[0] = fv[0]; 56 | v->fv[1] = fv[1]; 57 | return v; 58 | } 59 | 60 | struct variant* var_set3fv(struct variant* v, const float* fv) 61 | { 62 | v->type = VAR_TYPE_FLOAT3; 63 | v->fv[0] = fv[0]; 64 | v->fv[1] = fv[1]; 65 | v->fv[2] = fv[2]; 66 | return v; 67 | } 68 | 69 | struct variant* var_set4fv(struct variant* v, const float* fv) 70 | { 71 | v->type = VAR_TYPE_FLOAT4; 72 | v->fv[0] = fv[0]; 73 | v->fv[1] = fv[1]; 74 | v->fv[2] = fv[2]; 75 | v->fv[3] = fv[3]; 76 | return v; 77 | } 78 | 79 | struct variant* var_set2iv(struct variant* v, const int* iv) 80 | { 81 | v->type = VAR_TYPE_INT2; 82 | v->iv[0] = iv[0]; 83 | v->iv[1] = iv[1]; 84 | return v; 85 | } 86 | 87 | struct variant* var_set3iv(struct variant* v, const int* iv) 88 | { 89 | v->type = VAR_TYPE_INT3; 90 | v->iv[0] = iv[0]; 91 | v->iv[1] = iv[1]; 92 | v->iv[2] = iv[2]; 93 | return v; 94 | } 95 | 96 | struct variant* var_set4iv(struct variant* v, const int* iv) 97 | { 98 | v->type = VAR_TYPE_INT4; 99 | v->iv[0] = iv[0]; 100 | v->iv[1] = iv[1]; 101 | v->iv[2] = iv[2]; 102 | v->iv[3] = iv[3]; 103 | return v; 104 | } 105 | 106 | struct variant* var_set2f(struct variant* v, float x, float y) 107 | { 108 | v->type = VAR_TYPE_FLOAT2; 109 | v->fv[0] = x; 110 | v->fv[1] = y; 111 | return v; 112 | } 113 | 114 | struct variant* var_set3f(struct variant* v, float x, float y, float z) 115 | { 116 | v->type = VAR_TYPE_FLOAT3; 117 | v->fv[0] = x; 118 | v->fv[1] = y; 119 | v->fv[2] = z; 120 | return v; 121 | } 122 | 123 | struct variant* var_set4f(struct variant* v, float x, float y, float z, float w) 124 | { 125 | v->type = VAR_TYPE_FLOAT4; 126 | v->fv[0] = x; 127 | v->fv[1] = y; 128 | v->fv[2] = z; 129 | v->fv[3] = w; 130 | return v; 131 | } 132 | 133 | struct variant* var_set2i(struct variant* v, int x, int y) 134 | { 135 | v->type = VAR_TYPE_INT2; 136 | v->iv[0] = x; 137 | v->iv[1] = y; 138 | return v; 139 | } 140 | 141 | struct variant* var_set3i(struct variant* v, int x, int y, int z) 142 | { 143 | v->type = VAR_TYPE_INT3; 144 | v->iv[0] = x; 145 | v->iv[1] = y; 146 | v->iv[2] = z; 147 | return v; 148 | } 149 | 150 | struct variant* var_set4i(struct variant* v, int x, int y, int z, int w) 151 | { 152 | v->type = VAR_TYPE_INT4; 153 | v->iv[0] = x; 154 | v->iv[1] = y; 155 | v->iv[2] = z; 156 | v->iv[3] = w; 157 | return v; 158 | } 159 | 160 | struct variant* var_sets(struct variant* v, const char* str) 161 | { 162 | v->type = VAR_TYPE_STRING; 163 | str_safecpy(v->str, sizeof(v->str), str); 164 | return v; 165 | } 166 | 167 | struct variant* var_setui(struct variant* v, uint ui) 168 | { 169 | v->type = VAR_TYPE_UINT; 170 | v->ui = ui; 171 | return v; 172 | } 173 | 174 | int var_geti(const struct variant* v) 175 | { 176 | ASSERT(v->type == VAR_TYPE_INT); 177 | return v->i; 178 | } 179 | 180 | uint var_getui(const struct variant* v) 181 | { 182 | ASSERT(v->type == VAR_TYPE_UINT); 183 | return v->ui; 184 | } 185 | 186 | float var_getf(const struct variant* v) 187 | { 188 | ASSERT(v->type == VAR_TYPE_FLOAT); 189 | return v->f; 190 | } 191 | 192 | int var_getb(const struct variant* v) 193 | { 194 | ASSERT(v->type == VAR_TYPE_BOOL); 195 | return v->b; 196 | } 197 | 198 | const float* var_getfv(const struct variant* v) 199 | { 200 | ASSERT(v->type == VAR_TYPE_FLOAT2 || v->type == VAR_TYPE_FLOAT3 || v->type == VAR_TYPE_FLOAT4); 201 | return v->fv; 202 | } 203 | 204 | const int* var_getiv(const struct variant* v) 205 | { 206 | ASSERT(v->type == VAR_TYPE_INT2 || v->type == VAR_TYPE_INT3 || v->type == VAR_TYPE_INT4); 207 | return v->iv; 208 | } 209 | 210 | const char* var_gets(const struct variant* v) 211 | { 212 | ASSERT(v->type == VAR_TYPE_STRING); 213 | return v->str; 214 | } 215 | -------------------------------------------------------------------------------- /include/dhcore/linked-list.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | 17 | #ifndef __LINKEDLIST_H__ 18 | #define __LINKEDLIST_H__ 19 | 20 | #include "types.h" 21 | #include "core-api.h" 22 | 23 | /** 24 | * @defgroup ll Linked-list 25 | * Common linked-list structure 26 | * Usage :\n 27 | * For each data type (structure) that you need to make it linked-list\n 28 | * Define linked_list data in it, I call it 'node'.\n 29 | * Keep track of root link in the parent structure (structure owning the linked-list)\n 30 | * By defining a pointer to linked_list in it, I call it 'first'\n 31 | * Use **first** as plist in linked-list functions.\n 32 | * Use **node** as item in linked-list functions.\n 33 | * provide owner structure for each node in list_add/list_remove functions to reference the owner\n 34 | * Example: \n @code 35 | * struct my_listitem { 36 | * struct linked_list node; 37 | * uint my_id; 38 | * }; 39 | * 40 | * // add to list 41 | * struct my_listitem items[10]; 42 | * struct linked_list* my_list = NULL; 43 | * for (uint i = 0; i < 10; i++) { 44 | * list_add(&my_list, &items[i].node, &items[i]); 45 | * } 46 | * // iterate 47 | * struct linked_list* node = my_list; 48 | * while (node != NULL) { 49 | * struct my_listitem* item = node->data; 50 | * printf("ID: %d\n", item->my_id); 51 | * node = node->next; 52 | * } 53 | * @endcode 54 | * @ingroup ll 55 | * @see list_add 56 | * @see list_addlast 57 | * @see list_remove 58 | */ 59 | struct linked_list 60 | { 61 | struct linked_list* next; 62 | struct linked_list* prev; 63 | void* data; 64 | 65 | #ifdef __cplusplus 66 | linked_list() : next(NULL), prev(NULL) {} 67 | #endif 68 | }; 69 | 70 | /** 71 | * add item to the linked-list, this function adds the list_item to the head of the list \n 72 | * so linked_list pointer will be swaped with new item 73 | * @param plist pointer to the root item of the list (can be NULL) 74 | * @param item new item to be added 75 | * @param data custom data pointer, mostly owner of the list 'item' 76 | * @ingroup ll 77 | */ 78 | INLINE void list_add(struct linked_list** plist, struct linked_list* item, void* data) 79 | { 80 | item->next = (*plist); 81 | item->prev = NULL; 82 | if (*plist != NULL) 83 | (*plist)->prev = item; 84 | *plist = item; 85 | item->data = data; 86 | } 87 | 88 | /** 89 | * add item to the end of the linked-list 90 | * @see list_add @ingroup ll 91 | */ 92 | INLINE void list_addlast(struct linked_list** plist, struct linked_list* item, void* data) 93 | { 94 | if (*plist != NULL) { 95 | struct linked_list* last = *plist; 96 | while (last->next != NULL) last = last->next; 97 | last->next = item; 98 | item->prev = last; 99 | item->next = NULL; 100 | } else { 101 | *plist = item; 102 | item->prev = item->next = NULL; 103 | } 104 | 105 | item->data = data; 106 | } 107 | 108 | /** 109 | * remove item from linked-list 110 | * @param plist pointer to the root item the list, if the last item is removed *plist will be NULL 111 | * @param item item that will be removed 112 | * @ingroup ll 113 | */ 114 | INLINE void list_remove(struct linked_list** plist, struct linked_list* item) 115 | { 116 | if (item->next != NULL) item->next->prev = item->prev; 117 | if (item->prev != NULL) item->prev->next = item->next; 118 | if (*plist == item) *plist = item->next; 119 | item->next = item->prev = NULL; 120 | } 121 | 122 | #ifdef __cplusplus 123 | namespace dh { 124 | // _T: container type for LinkedList's data 125 | template 126 | class LinkedList 127 | { 128 | private: 129 | LinkedList<_T> *m_next = nullptr; 130 | LinkedList<_T> *m_prev = nullptr; 131 | _T m_data; 132 | 133 | public: 134 | LinkedList() = default; 135 | _T data() const { return m_data; } 136 | LinkedList<_T>* next() const { return m_next; } 137 | LinkedList<_T>* prev() const { return m_prev; } 138 | 139 | public: 140 | 141 | static void add(LinkedList<_T> **plist, LinkedList<_T> *new_item, _T data) 142 | { 143 | new_item->m_next = (*plist); 144 | new_item->m_prev = nullptr; 145 | if (*plist) 146 | (*plist)->m_prev = new_item; 147 | *plist = new_item; 148 | new_item->m_data = data; 149 | } 150 | 151 | static void add_last(LinkedList<_T> **plist, LinkedList<_T> *new_item, _T data) 152 | { 153 | if (*plist) { 154 | LinkedList<_T> *last = *plist; 155 | while (last->m_next) 156 | last = last->m_next; 157 | last->m_next = new_item; 158 | new_item->m_prev = last; 159 | new_item->m_next = nullptr; 160 | } else { 161 | *plist = new_item; 162 | new_item->m_prev = new_item->m_next = nullptr; 163 | } 164 | 165 | new_item->m_data = data; 166 | } 167 | 168 | static void remove(LinkedList<_T> **plist, LinkedList<_T> *item) 169 | { 170 | if (item->m_next) 171 | item->m_next->m_prev = item->m_prev; 172 | if (item->m_prev) 173 | item->m_prev->m_next = item->m_next; 174 | if (*plist == item) 175 | *plist = item->m_next; 176 | item->m_next = item->m_prev = nullptr; 177 | } 178 | }; 179 | } 180 | #endif 181 | 182 | #endif /* __LINKEDLIST_H__ */ 183 | -------------------------------------------------------------------------------- /include/dhcore/util.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | 17 | #ifndef UTIL_H_ 18 | #define UTIL_H_ 19 | 20 | /** 21 | * @defgroup util Utility 22 | */ 23 | 24 | #include "types.h" 25 | #include "core-api.h" 26 | #include "allocator.h" 27 | 28 | /* terminal ANSI colors for UNIX console only 29 | In case of windows, we will translate these to API calls internally 30 | */ 31 | #if defined(_POSIXLIB_) && !defined(_MOBILE_) 32 | #define TERM_RESET "\033[0m" 33 | #define TERM_DIM "\033[2m" 34 | #define TERM_BLACK "\033[30m" /* Black */ 35 | #define TERM_GREY "\033[90m" /* Grey */ 36 | #define TERM_RED "\033[31m" /* Red */ 37 | #define TERM_GREEN "\033[32m" /* Green */ 38 | #define TERM_YELLOW "\033[33m" /* Yellow */ 39 | #define TERM_BLUE "\033[34m" /* Blue */ 40 | #define TERM_MAGENTA "\033[35m" /* Magenta */ 41 | #define TERM_CYAN "\033[36m" /* Cyan */ 42 | #define TERM_WHITE "\033[37m" /* White */ 43 | #define TERM_BOLDBLACK "\033[1m\033[30m" /* Bold Black */ 44 | #define TERM_BOLDGREY "\033[1m\033[90m" /* Bold Grey */ 45 | #define TERM_BOLDRED "\033[1m\033[31m" /* Bold Red */ 46 | #define TERM_BOLDGREEN "\033[1m\033[32m" /* Bold Green */ 47 | #define TERM_BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */ 48 | #define TERM_BOLDBLUE "\033[1m\033[34m" /* Bold Blue */ 49 | #define TERM_BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */ 50 | #define TERM_BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */ 51 | #define TERM_BOLDWHITE "\033[1m\033[37m" /* Bold White */ 52 | #define TERM_DIMBLACK "\033[2;30m" /* Dim Black */ 53 | #define TERM_DIMRED "\033[2;31m" /* Dim Red */ 54 | #define TERM_DIMGREEN "\033[2;32m" /* Dim Green */ 55 | #define TERM_DIMYELLOW "\033[2;33m" /* Dim Yellow */ 56 | #define TERM_DIMBLUE "\033[2;34m" /* Dim Blue */ 57 | #define TERM_DIMMAGENTA "\033[2;35m" /* Dim Magenta */ 58 | #define TERM_DIMCYAN "\033[2;36m" /* Dim Cyan */ 59 | #define TERM_DIMWHITE "\033[2;37m" /* Dim White */ 60 | #else 61 | #define TERM_RESET "" 62 | #define TERM_DIM "" 63 | #define TERM_BLACK "" 64 | #define TERM_GREY "" 65 | #define TERM_RED "" 66 | #define TERM_GREEN "" 67 | #define TERM_YELLOW "" 68 | #define TERM_BLUE "" 69 | #define TERM_MAGENTA "" 70 | #define TERM_CYAN "" 71 | #define TERM_WHITE "" 72 | #define TERM_BOLDBLACK "" 73 | #define TERM_BOLDGREY "" 74 | #define TERM_BOLDRED "" 75 | #define TERM_BOLDGREEN "" 76 | #define TERM_BOLDYELLOW "" 77 | #define TERM_BOLDBLUE "" 78 | #define TERM_BOLDMAGENTA "" 79 | #define TERM_BOLDCYAN "" 80 | #define TERM_BOLDWHITE "" 81 | #define TERM_DIMBLACK "" 82 | #define TERM_DIMRED "" 83 | #define TERM_DIMGREEN "" 84 | #define TERM_DIMYELLOW "" 85 | #define TERM_DIMBLUE "" 86 | #define TERM_DIMMAGENTA "" 87 | #define TERM_DIMCYAN "" 88 | #define TERM_DIMWHITE "" 89 | #endif 90 | 91 | /** 92 | * runs system command and returns console output result in null-terminated string\n 93 | * note that returned string must be freed (FREE) after use 94 | * @ingroup util 95 | */ 96 | CORE_API char* util_runcmd(const char* cmd); 97 | 98 | /** 99 | * returns current executable directory 100 | * @param outdir: preallocated output directory string 101 | * @param outsize: size of characters in 'outstr' 102 | * @return: outstr 103 | * @ingroup util 104 | */ 105 | CORE_API char* util_getexedir(char* outdir); 106 | 107 | /** 108 | * stalls the program and gets a character from input 109 | * @ingroup util 110 | */ 111 | CORE_API char util_getch(); 112 | 113 | /** 114 | * returns current user profile directory \n 115 | * (/home/$user under linux, /My Documents under win) 116 | * @param outdir: preallocated output directory string 117 | * @return: outdir 118 | * @ingroup util 119 | */ 120 | CORE_API char* util_getuserdir(char* outdir); 121 | 122 | /** 123 | * returns temp directory 124 | * @ingroup util 125 | */ 126 | CORE_API char* util_gettempdir(char* outdir); 127 | 128 | /** 129 | * Returns config directory 130 | * @ingroup util 131 | */ 132 | CORE_API char* util_getconfdir(char* outdir); 133 | 134 | /** 135 | * creates a directory 136 | * @return TRUE if successful 137 | * @ingroup util 138 | */ 139 | CORE_API int util_makedir(const char* dir); 140 | 141 | /** 142 | * copies a file from source to destination 143 | * @return TRUE if successful 144 | * @ingroup util 145 | */ 146 | CORE_API int util_copyfile(const char* dest, const char* src); 147 | 148 | /** 149 | * deletees a file from disk 150 | * @return TRUE if success 151 | * @ingroup util 152 | */ 153 | CORE_API int util_delfile(const char* filepath); 154 | 155 | /** 156 | * moves a file from source to destination path 157 | * @return TRUE if success 158 | * @ingroup util 159 | */ 160 | CORE_API int util_movefile(const char* dest, const char* src); 161 | 162 | /** 163 | * checks if specified path is a directory 164 | * @return TRUE if path is directory 165 | * @ingroup util 166 | */ 167 | CORE_API int util_pathisdir(const char* path); 168 | 169 | /** 170 | * stalls program and sleeps for N milliseconds 171 | * @param msecs number of milliseconds to sleep 172 | * @ingroup util 173 | */ 174 | CORE_API void util_sleep(uint msecs); 175 | 176 | /** 177 | * loads a text file from disk and returns string buffer \n 178 | * @param filepath path of the text 179 | * @return null-terminated string containing file text, must be freed after use (use A_FREE) 180 | * @ingroup util 181 | */ 182 | CORE_API char* util_readtextfile(const char* txt_filepath, struct allocator* alloc); 183 | 184 | CORE_API void util_ttyecho(); 185 | 186 | #endif /* UTIL_H_ */ 187 | -------------------------------------------------------------------------------- /include/dhcore/commander.h: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // commander.h 4 | // 5 | // Copyright (c) 2012 TJ Holowaychuk 6 | // 7 | 8 | /* Sepehr Taghdisian: I modified the API to be able to export functions as DLL 9 | * Also added more support for positional arguments */ 10 | 11 | #ifndef COMMANDER_H 12 | #define COMMANDER_H 13 | 14 | /** 15 | * @defgroup cmd Command line parser 16 | * Simple command line parser, from a code by TJ Holowaychuk\n 17 | * Example:\n 18 | * @code 19 | * int verbose = FALSE; 20 | * char filepath[255]; 21 | * 22 | * // callback for parsing @e verbose argument 23 | * static void cmdline_verbose(command_t* cmd, void* param) 24 | * { 25 | * verbose = TRUE; 26 | * } 27 | * // callback for parsing @e filepath argument 28 | * static void cmdline_filepath(command_t* cmd, void* param) 29 | * { 30 | * strcpy(filepath, cmd->arg); 31 | * } 32 | * 33 | * int main(int argc, char** argv) 34 | * { 35 | * command_t cmd; 36 | * command_init(&cmd, "myapp", "1.0"); 37 | * command_option(&cmd, "-v", "--verbose", "Verbose mode", cmdline_verbose); 38 | * command_option_pos(&cmd, "filepath", "Source filepath", cmdline_filepath); // positional arg 39 | * command_parse(&cmd, argc, argv, NULL); 40 | * command_free(&cmd); 41 | * return 0; 42 | * } 43 | * @endcode 44 | * @ingroup cmd 45 | */ 46 | 47 | #include "core-api.h" 48 | 49 | /* 50 | * Max options that can be defined. 51 | */ 52 | 53 | #ifndef COMMANDER_MAX_OPTIONS 54 | #define COMMANDER_MAX_OPTIONS 32 55 | #endif 56 | 57 | /* 58 | * Max arguments that can be passed. 59 | */ 60 | 61 | #ifndef COMMANDER_MAX_ARGS 62 | #define COMMANDER_MAX_ARGS 32 63 | #endif 64 | 65 | /* 66 | * Command struct. 67 | */ 68 | 69 | struct command; 70 | 71 | /** 72 | * Callback function for parsing arguments\n 73 | * @param self Commander object that is used to parse arguments, @e self->arg is the optional 74 | * argument value or is NULL if no value is provided. 75 | * @see command_option 76 | * @see command_option_pos 77 | * @ingroup cmd 78 | */ 79 | typedef void (* command_callback_t)(struct command *self, void* param); 80 | 81 | /* 82 | * Command option. 83 | */ 84 | 85 | typedef struct { 86 | int optional_arg; 87 | int required_arg; 88 | char *argname; 89 | char *large; 90 | const char *small; 91 | const char *large_with_arg; 92 | const char *description; 93 | command_callback_t cb; 94 | } command_option_t; 95 | 96 | typedef struct { 97 | const char* name; 98 | const char* description; 99 | int optional; 100 | command_callback_t cb; 101 | } command_option_pos_t; 102 | 103 | /* 104 | * Command. 105 | */ 106 | 107 | typedef struct command { 108 | void *data; 109 | const char *usage; 110 | const char *arg; 111 | const char *name; 112 | const char *version; 113 | int option_count; 114 | command_option_t options[COMMANDER_MAX_OPTIONS]; 115 | int pos_count; 116 | command_option_pos_t poss[COMMANDER_MAX_ARGS]; 117 | int argc; 118 | char *argv[COMMANDER_MAX_ARGS]; 119 | char **nargv; 120 | } command_t; 121 | 122 | 123 | /** 124 | * Initialize command line parser 125 | * @param self A valid commander object 126 | * @param name Name of the application 127 | * @param version Version of the application 128 | * @ingroup cmd 129 | */ 130 | CORE_API void command_init(command_t *self, const char *name, const char *version); 131 | 132 | /** 133 | * Free command line parser 134 | * @ingroup cmd 135 | */ 136 | CORE_API void command_free(command_t *self); 137 | 138 | /** 139 | * Adds command line argument 140 | * @param self Commander object 141 | * @param small Short argument name (example: "-v") 142 | * @param large Long argument name (example: "--verbose"). Long argument name can contain optional or 143 | * required value, for example "--file " defines a @e --file argument with mandatory 144 | * "filename" argument (accessed with cmd->arg in callbacks), and "--file [filename]" defines a @e --file 145 | * argument with optional "filename" argument (in case of no filename, cmd->arg is NULL). 146 | * @param desc Description message for argument. Can be seen with @e --help flag 147 | * @param cb Callback function for parsing argument value 148 | * @ingroup cmd 149 | */ 150 | CORE_API void command_option(command_t *self, const char *small, const char *large, 151 | const char *desc, command_callback_t cb); 152 | 153 | /** 154 | * Adds positional command line argument 155 | * @param self Commander object 156 | * @param name Argument name, shown in help 157 | * @param desc Argument description 158 | * @param optional Boolean value that defines if argument can be optional or mandatory 159 | * @param cb Callback function for pasrsing argument value (accessed with command_t->arg) 160 | * @ingroup cmd 161 | */ 162 | CORE_API void command_option_pos(command_t *self, const char *name, const char* desc, 163 | int optional, command_callback_t cb); 164 | 165 | /** 166 | * Parses command line arguments from @e main function inputs. Must be called after initialization 167 | * and arguments setup 168 | * @param self Commander object 169 | * @param argc Number of total arguments (from the main function) 170 | * @param argv Actual command line arguments (from the main function) 171 | * @param param Custom user-defined pointer, this pointer will be passed to callbacks 172 | * @ingroup cmd 173 | */ 174 | CORE_API void command_parse(command_t *self, int argc, char **argv, void* param); 175 | 176 | #ifdef __cplusplus 177 | namespace dh { 178 | class CommandArgs 179 | { 180 | private: 181 | command_t m_cmd; 182 | 183 | public: 184 | CommandArgs(const char *name, const char *version = "1.0") 185 | { 186 | command_init(&m_cmd, name, version); 187 | } 188 | 189 | ~CommandArgs() 190 | { 191 | command_free(&m_cmd); 192 | } 193 | 194 | void add_option(const char *small, const char *large, const char *desc, command_callback_t cb) 195 | { 196 | command_option(&m_cmd, small, large, desc, cb); 197 | } 198 | 199 | void add_option_positional(const char *name, const char *desc, command_callback_t cb, 200 | bool optional) 201 | { 202 | command_option_pos(&m_cmd, name, desc, optional, cb); 203 | } 204 | 205 | void parse(int argc, char **argv, void *user_param = nullptr) 206 | { 207 | command_parse(&m_cmd, argc, argv, user_param); 208 | } 209 | }; 210 | 211 | } 212 | #endif 213 | 214 | #endif /* COMMANDER_H */ 215 | -------------------------------------------------------------------------------- /src/core/path.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "dhcore/path.h" 21 | 22 | #if defined(_WIN_) 23 | #include "dhcore/win.h" 24 | #include 25 | #endif 26 | 27 | #ifdef _POSIXLIB_ 28 | #include 29 | #include 30 | #include 31 | #endif 32 | 33 | #if defined(_WIN_) 34 | #define SEP_CHAR '\\' 35 | #else 36 | #define SEP_CHAR '/' 37 | #endif 38 | 39 | char* path_norm(char* outpath, const char* inpath) 40 | { 41 | if (inpath[0] == 0) { 42 | outpath[0] = 0; 43 | return outpath; 44 | } 45 | 46 | #if defined(_WIN_) 47 | char tmp[DH_PATH_MAX]; 48 | GetFullPathName(inpath, DH_PATH_MAX, tmp, NULL); 49 | path_towin(outpath, tmp); 50 | size_t sz = strlen(outpath); 51 | if (outpath[sz-1] == '\\') 52 | outpath[sz-1] = 0; 53 | return outpath; 54 | #else 55 | 56 | char* tmp = realpath(inpath, NULL); 57 | if (tmp != NULL) { 58 | path_tounix(outpath, tmp); 59 | free(tmp); 60 | } else { 61 | char tmp2[DH_PATH_MAX]; 62 | realpath(inpath, tmp2); 63 | strcpy(outpath, tmp2); 64 | } 65 | 66 | size_t sz = strlen(outpath); 67 | if (outpath[sz-1] == '/') 68 | outpath[sz-1] = 0; 69 | return outpath; 70 | #endif 71 | } 72 | 73 | char* path_tounix(char* outpath, const char* inpath) 74 | { 75 | char tmp[DH_PATH_MAX]; 76 | strcpy(tmp, inpath); 77 | str_replace(tmp, '\\', '/'); 78 | strcpy(outpath, tmp); 79 | return outpath; 80 | } 81 | 82 | char* path_towin(char* outpath, const char* inpath) 83 | { 84 | char tmp[DH_PATH_MAX]; 85 | strcpy(tmp, inpath); 86 | str_replace(tmp, '/', '\\'); 87 | strcpy(outpath, tmp); 88 | return outpath; 89 | } 90 | 91 | char* path_getdir(char* outpath, const char* inpath) 92 | { 93 | /* to prevent aliasing */ 94 | char tmp[DH_PATH_MAX]; 95 | strcpy(tmp, inpath); 96 | 97 | /* Path with '/' or '\\' at the End */ 98 | char* r = strrchr(tmp, '/'); 99 | if (r == NULL) r = strrchr(tmp, '\\'); 100 | if (r != NULL) { strncpy(tmp, inpath, (r - tmp)); tmp[r - tmp] = 0; } 101 | else tmp[0] = 0; 102 | 103 | strcpy(outpath, tmp); 104 | return outpath; 105 | } 106 | 107 | char* path_getfilename(char* outpath, const char* inpath) 108 | { 109 | char tmp[DH_PATH_MAX]; 110 | 111 | const char *ri = strrchr(inpath, '/'); 112 | if (ri == NULL) ri = strrchr(inpath, '\\'); 113 | if (ri != NULL) strcpy(tmp, ri + 1); 114 | else strcpy(tmp, inpath); 115 | 116 | /* Name only */ 117 | char *r = strrchr(tmp, '.'); 118 | if (r != NULL) *r = 0; 119 | 120 | strcpy(outpath, tmp); 121 | return outpath; 122 | } 123 | 124 | char* path_getfileext(char* outpath, const char* inpath) 125 | { 126 | char tmp[DH_PATH_MAX]; /* Prevent Aliasing */ 127 | 128 | const char *r = strrchr(inpath, '.'); 129 | if (r != NULL) strcpy(tmp, r + 1); 130 | else tmp[0] = 0; 131 | 132 | r = strchr(tmp, '/'); 133 | 134 | strcpy(outpath, (r != NULL) ? (r + 1) : tmp); 135 | return outpath; 136 | } 137 | 138 | char* path_getfullfilename(char* outpath, const char* inpath) 139 | { 140 | char tmp[DH_PATH_MAX]; /* Prevent Aliasing */ 141 | 142 | const char *r = strrchr(inpath, '/'); 143 | if (r == NULL) r = strrchr(inpath, '\\'); 144 | if (r != NULL) strcpy(tmp, r + 1); 145 | else strcpy(tmp, inpath); 146 | 147 | strcpy(outpath, tmp); 148 | return outpath; 149 | } 150 | 151 | char* path_goup(char* outpath, const char* inpath) 152 | { 153 | char tmp[DH_PATH_MAX]; 154 | strcpy(tmp, inpath); 155 | size_t s = strlen(tmp); 156 | 157 | if (tmp[s-1] == '/' || tmp[s-1] == '\\') 158 | tmp[s-1] = 0; 159 | 160 | /* handle case when the path is like 'my/path/./' */ 161 | if (s>3 && tmp[s-2] == '.' && (tmp[s-3] == '/' || tmp[s-3] == '\\')) 162 | tmp[s-3] = 0; 163 | /* handle case when the path is like 'my/path/.' */ 164 | if (s>2 && tmp[s-1] == '.' && (tmp[s-2] == '/' || tmp[s-2] == '\\')) 165 | tmp[s-2] = 0; 166 | 167 | char* up = strrchr(tmp, '/'); 168 | if (up == NULL) 169 | up = strrchr(tmp, '\\'); 170 | 171 | if (up != NULL) 172 | *up = 0; 173 | 174 | strcpy(outpath, tmp); 175 | return outpath; 176 | } 177 | 178 | int path_exists(const char* inpath) 179 | { 180 | #ifdef _POSIXLIB_ 181 | struct stat s; 182 | if (stat(inpath, &s) == 0) { 183 | if (s.st_mode & S_IFDIR) 184 | return 2; 185 | else if ((s.st_mode & (S_IFREG|S_IFLNK))) 186 | return 1; 187 | else 188 | return 0; 189 | 190 | } else { 191 | return FALSE; 192 | } 193 | #elif defined(_WIN_) 194 | if (PathIsDirectory(inpath)) 195 | return 2; 196 | else if (PathFileExists(inpath)) 197 | return 1; 198 | else 199 | return 0; 200 | #endif 201 | } 202 | 203 | char* path_join(char* outpath, const char* join0, const char* join1, ...) 204 | { 205 | char tmp[DH_PATH_MAX]; 206 | char sep[] = {SEP_CHAR, 0}; 207 | 208 | if (join0[0] != 0) { 209 | strcpy(tmp, join0); 210 | strcat(tmp, sep); 211 | strcat(tmp, join1); 212 | } else { 213 | strcpy(tmp, join1); 214 | } 215 | 216 | va_list args; 217 | va_start(args, join1); 218 | const char* join2; 219 | while ((join2 = va_arg(args, const char*)) != NULL) { 220 | strcat(tmp, sep); 221 | strcat(tmp, join2); 222 | } 223 | va_end(args); 224 | 225 | return strcpy(outpath, tmp); 226 | } 227 | -------------------------------------------------------------------------------- /src/core/errors.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #if defined(_WIN_) 17 | #include "dhcore/win.h" 18 | #endif 19 | 20 | #include 21 | #include 22 | 23 | #include "dhcore/err.h" 24 | #include "dhcore/mem-mgr.h" 25 | #include "dhcore/log.h" 26 | #include "dhcore/mt.h" 27 | 28 | #define ERROR_STACK_MAX 32 29 | 30 | struct err_desc 31 | { 32 | char text[1024]; 33 | #if defined(_DEBUG_) 34 | char src_filepath[DH_PATH_MAX]; 35 | uint line; 36 | #endif 37 | }; 38 | 39 | struct err_mgr 40 | { 41 | struct err_desc* err_stack; /* array of error stacks (see err_desc) */ 42 | char* err_string; /* whole error string that is created when needed */ 43 | long volatile err_cnt; /* number of error items in the stack */ 44 | long volatile err_code; /* last error code */ 45 | mt_mutex mtx; 46 | }; 47 | 48 | /* globals */ 49 | static struct err_mgr* g_err = NULL; 50 | 51 | /* */ 52 | void err_reportassert(const char* expr, const char* source, uint line) 53 | { 54 | char msg[512]; 55 | sprintf(msg, "ASSERTION FAILURE: Expression '%s': %s(line: %d)\n", expr, source, line); 56 | 57 | #if defined(_WIN_) 58 | MessageBox(NULL, msg, "ASSERT", MB_OK | MB_ICONWARNING); 59 | #if defined(_MSVC_) && defined(_DEBUG_) 60 | OutputDebugString(msg); 61 | #endif 62 | #else 63 | puts(msg); 64 | #endif 65 | } 66 | 67 | result_t err_init() 68 | { 69 | if (g_err != NULL) 70 | return RET_FAIL; 71 | g_err = (struct err_mgr*)ALLOC(sizeof(struct err_mgr), 0); 72 | if (g_err == NULL) 73 | return RET_OUTOFMEMORY; 74 | memset(g_err, 0x00, sizeof(struct err_mgr)); 75 | 76 | g_err->err_stack = (struct err_desc*)ALLOC(sizeof(struct err_desc)*ERROR_STACK_MAX, 0); 77 | g_err->err_string = (char*)ALLOC(ERROR_STACK_MAX*1024, 0); 78 | if (g_err->err_stack == NULL || g_err->err_string == NULL) { 79 | err_release(); 80 | return RET_OUTOFMEMORY; 81 | } 82 | 83 | mt_mutex_init(&g_err->mtx); 84 | 85 | g_err->err_string[0] = 0; 86 | return RET_OK; 87 | } 88 | 89 | void err_release() 90 | { 91 | if (g_err != NULL) { 92 | if (g_err->err_stack != NULL) { 93 | FREE(g_err->err_stack); 94 | g_err->err_stack = NULL; 95 | } 96 | 97 | if (g_err->err_string != NULL) { 98 | FREE(g_err->err_string); 99 | g_err->err_string = NULL; 100 | } 101 | 102 | mt_mutex_release(&g_err->mtx); 103 | FREE(g_err); 104 | g_err = NULL; 105 | } 106 | } 107 | 108 | void err_printf(const char* source, uint line, const char* fmt, ...) 109 | { 110 | char text[1024]; 111 | va_list args; 112 | va_start(args, fmt); 113 | vsnprintf(text, sizeof(text), fmt, args); 114 | va_end(args); 115 | err_print(source, line, text); 116 | } 117 | 118 | result_t err_printn(const char* source, uint line, uint err_code) 119 | { 120 | const char* text; 121 | switch (err_code) { 122 | case RET_OK: text = "No errors!"; break; 123 | case RET_FAIL: text = "Generic fatal error"; break; 124 | case RET_OUTOFMEMORY: text = "Insufficient memory"; break; 125 | case RET_WARNING: text = "Non-fatal error"; break; 126 | case RET_INVALIDARG: text = "Invalid arguments"; break; 127 | case RET_FILE_ERROR: text = "File open failed"; break; 128 | case RET_INVALIDCALL: text = "Command not found"; break; 129 | case RET_NOT_IMPL: text = "Not implemented"; break; 130 | default: text = "Unknown error!"; break; 131 | } 132 | 133 | MT_ATOMIC_SET(g_err->err_code, (long)err_code); 134 | err_print(source, line, text); 135 | return err_code; 136 | } 137 | 138 | 139 | void err_print(const char* source, uint line, const char* text) 140 | { 141 | if (g_err->err_cnt == ERROR_STACK_MAX) 142 | return; 143 | 144 | mt_mutex_lock(&g_err->mtx); 145 | uint idx = (uint)g_err->err_cnt; 146 | strcpy(g_err->err_stack[idx].text, text); 147 | 148 | #if defined(_DEBUG_) 149 | strcpy(g_err->err_stack[idx].src_filepath, source); 150 | g_err->err_stack[idx].line = line; 151 | #endif 152 | mt_mutex_unlock(&g_err->mtx); 153 | 154 | MT_ATOMIC_INCR(g_err->err_cnt); 155 | } 156 | 157 | void err_sendtolog(int as_warning) 158 | { 159 | const char* text = err_getstring(); 160 | if (as_warning) 161 | log_print(LOG_WARNING, text); 162 | else 163 | log_print(LOG_ERROR, text); 164 | } 165 | 166 | const char* err_getstring() 167 | { 168 | ASSERT(g_err->err_string); 169 | 170 | char err_line[2048]; 171 | 172 | mt_mutex_lock(&g_err->mtx); 173 | g_err->err_string[0] = '\n'; 174 | g_err->err_string[1] = 0; 175 | 176 | if (g_err->err_cnt > 0) { 177 | for (int i = 0; i < (int)g_err->err_cnt; i++) { 178 | sprintf(err_line, "%d) %s\n", i, g_err->err_stack[i].text); 179 | strcat(g_err->err_string, err_line); 180 | } 181 | 182 | /* for debug releases, output the call stack too */ 183 | #if defined(_DEBUG_) 184 | strcat(g_err->err_string, "CALL STACK: \n"); 185 | for (int i = 0; i < (int)g_err->err_cnt; i++) { 186 | sprintf(err_line, "\t%d) %s (line: %d)\n", 187 | i, 188 | g_err->err_stack[i].src_filepath, 189 | g_err->err_stack[i].line); 190 | strcat(g_err->err_string, err_line); 191 | } 192 | #endif 193 | 194 | /* reset error count, so we can build another error stack later */ 195 | MT_ATOMIC_SET(g_err->err_cnt, 0); 196 | } 197 | 198 | mt_mutex_unlock(&g_err->mtx); 199 | return g_err->err_string; 200 | } 201 | 202 | uint err_getcode() 203 | { 204 | return (uint)g_err->err_code; 205 | } 206 | 207 | void err_clear() 208 | { 209 | MT_ATOMIC_SET(g_err->err_cnt, 0); 210 | } 211 | 212 | int err_haserrors() 213 | { 214 | return g_err->err_cnt != 0; 215 | } 216 | 217 | -------------------------------------------------------------------------------- /include/dhcore/numeric.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | #ifndef __NUMERIC_H__ 17 | #define __NUMERIC_H__ 18 | 19 | #include "types.h" 20 | #include "core-api.h" 21 | 22 | #if defined(PI) 23 | #undef PI 24 | #endif 25 | 26 | #if defined(EPSILON) 27 | #undef EPSILON 28 | #endif 29 | 30 | #define EPSILON 0.00001f 31 | #define PI 3.14159265f 32 | #define PI_2X 6.2831853f 33 | #define PI_HALF 1.570796325f 34 | 35 | /** 36 | * @defgroup num Numeric 37 | */ 38 | 39 | /** 40 | * initializes random seed by system timer 41 | * @ingroup num 42 | */ 43 | CORE_API void rand_seed(); 44 | 45 | /** 46 | * flips a count given a probability value 47 | * @param prob should be between 0~100, it is the chance of heads for the coin (true) - 48 | * which normally whould be 50 for 50-50 chance 49 | * @ingroup num 50 | */ 51 | CORE_API int rand_flipcoin(uint prob); 52 | 53 | /** 54 | * get a random value between two integer values , range = [min, max] 55 | * @ingroup num 56 | */ 57 | CORE_API int rand_geti(int min, int max); 58 | 59 | /** 60 | * get a random value between two floating-point values, range = [min, max] 61 | * @ingroup num 62 | */ 63 | CORE_API float rand_getf(float min, float max); 64 | 65 | /** 66 | * powers an integer value (base) to n 67 | * @ingroup num 68 | */ 69 | INLINE int powi(int base, int n) 70 | { 71 | if (n == 0) 72 | return 1; 73 | 74 | int r = base; 75 | for (int i = 1; i < n; i++) 76 | r *= base; 77 | return r; 78 | } 79 | 80 | /** 81 | * @brief Returns aligned value 82 | * @ingroup num 83 | */ 84 | INLINE int aligni(int val, int align) 85 | { 86 | int misalign = val & (align - 1); 87 | int adjust = align - misalign; 88 | return val + adjust; 89 | } 90 | 91 | /** 92 | * clamp input float value to [min_value, max_value] 93 | * @ingroup num 94 | */ 95 | INLINE float clampf(float value, float min_value, float max_value) 96 | { 97 | if (value < min_value) return min_value; 98 | else if (value > max_value) return max_value; 99 | else return value; 100 | } 101 | 102 | /** 103 | * clamp input integer value to [min_value, max_value] 104 | * @ingroup num 105 | */ 106 | INLINE int clampi(int value, int min_value, int max_value) 107 | { 108 | if (value < min_value) return min_value; 109 | else if (value > max_value) return max_value; 110 | else return value; 111 | } 112 | 113 | /** 114 | * clamp input unsigned integer value to [min_value, max_value] 115 | * @ingroup num 116 | */ 117 | INLINE uint clampui(uint value, uint min_value, uint max_value) 118 | { 119 | if (value < min_value) return min_value; 120 | else if (value > max_value) return max_value; 121 | else return value; 122 | } 123 | 124 | /** 125 | * clamp input size_t value to [min_value, max_value] 126 | * @ingroup num 127 | */ 128 | INLINE size_t clampsz(size_t value, size_t min_value, size_t max_value) 129 | { 130 | if (value < min_value) return min_value; 131 | else if (value > max_value) return max_value; 132 | else return value; 133 | } 134 | 135 | /** 136 | * return minimum of two float values 137 | * @ingroup num 138 | */ 139 | INLINE float minf(float n1, float n2) 140 | { 141 | return (n1 < n2) ? n1 : n2; 142 | } 143 | 144 | /** 145 | * return minimum of two integer values 146 | * @ingroup num 147 | */ 148 | INLINE int mini(int n1, int n2) 149 | { 150 | return (n1 < n2) ? n1 : n2; 151 | } 152 | 153 | /** 154 | * return minimum of two unsigned integer values 155 | * @ingroup num 156 | */ 157 | INLINE uint minui(uint n1, uint n2) 158 | { 159 | return (n1 < n2) ? n1 : n2; 160 | } 161 | 162 | /** 163 | * return maximum of two float values 164 | * @ingroup num 165 | */ 166 | INLINE float maxf(float n1, float n2) 167 | { 168 | return (n1 > n2) ? n1 : n2; 169 | } 170 | 171 | /** 172 | * return maximum of two integer values 173 | * @ingroup num 174 | */ 175 | INLINE int maxi(int n1, int n2) 176 | { 177 | return (n1 > n2) ? n1 : n2; 178 | } 179 | 180 | /** 181 | * return maximum of two unsigned integer values 182 | * @ingroup num 183 | */ 184 | INLINE uint maxui(uint n1, uint n2) 185 | { 186 | return (n1 > n2) ? n1 : n2; 187 | } 188 | 189 | /** 190 | * swap two float values with each other 191 | * @ingroup num 192 | */ 193 | INLINE void swapf(float* n1, float* n2) 194 | { 195 | float tmp = *n1; 196 | *n1 = *n2; 197 | *n2 = tmp; 198 | } 199 | 200 | /** 201 | * swap two integer values with each other 202 | * @ingroup num 203 | */ 204 | INLINE void swapi(int* n1, int* n2) 205 | { 206 | int tmp = *n1; 207 | *n1 = *n2; 208 | *n2 = tmp; 209 | } 210 | 211 | /** 212 | * swap two unsigned integer values with each other 213 | * @ingroup num 214 | */ 215 | INLINE void swapui(uint* n1, uint* n2) 216 | { 217 | uint tmp = *n1; 218 | *n1 = *n2; 219 | *n2 = tmp; 220 | } 221 | 222 | /** 223 | * swap two pointers with each other 224 | * @ingroup num 225 | */ 226 | INLINE void swapptr(void** pp1, void** pp2) 227 | { 228 | void* tmp = *pp1; 229 | *pp1 = *pp2; 230 | *pp2 = tmp; 231 | } 232 | 233 | #ifdef __cplusplus 234 | namespace dh { 235 | 236 | template 237 | T tmin(T v1, T v2) 238 | { 239 | return (v1 < v2) ? v1 : v2; 240 | } 241 | 242 | template 243 | T tmax(T v1, T v2) 244 | { 245 | return v1 > v2 ? v1 : v2; 246 | } 247 | 248 | template 249 | void tswap(T *v1, T *v2) 250 | { 251 | T tmp = *v1; 252 | *v1 = *v2; 253 | *v2 = tmp; 254 | } 255 | 256 | template 257 | T tclamp(T v, T v_min, T v_max) 258 | { 259 | if (v < v_min) return v_min; 260 | else if (v > v_max) return v_max; 261 | else return v; 262 | } 263 | 264 | template 265 | T talign(T val, T align) 266 | { 267 | T misalign = val & (align - 1); 268 | T adjust = align - misalign; 269 | return val + adjust; 270 | } 271 | 272 | 273 | } // dh 274 | #endif 275 | 276 | #endif /* __NUMERIC_H__ */ 277 | -------------------------------------------------------------------------------- /include/dhcore/mem-mgr.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * Copyright (c) 2012, Sepehr Taghdisian 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | ***********************************************************************************/ 15 | 16 | 17 | #ifndef __MEMMGR_H__ 18 | #define __MEMMGR_H__ 19 | 20 | #include "types.h" 21 | #include "core-api.h" 22 | #include "allocator.h" 23 | 24 | /** 25 | * @defgroup mem Memory 26 | */ 27 | 28 | /** 29 | * memory statistics structure 30 | * @see mem_getstats 31 | * @ingroup mem 32 | */ 33 | struct mem_stats 34 | { 35 | uint alloc_cnt; /**< allocation count */ 36 | size_t alloc_bytes; /**< total allocated bytes */ 37 | size_t limit_bytes; /**< maximum allowed heap allocation size, =0 if it's not limited */ 38 | size_t tracer_alloc_bytes; /**< total allocated bytes by memory tracer */ 39 | }; 40 | 41 | /* */ 42 | result_t mem_init(int trace_mem); 43 | void mem_release(); 44 | 45 | /** 46 | * Checks is memory system is initialized 47 | * @ingroup mem 48 | */ 49 | CORE_API int mem_isinit(); 50 | 51 | /** 52 | * Get memory statistics 53 | * @ingroup mem 54 | */ 55 | CORE_API void mem_getstats(struct mem_stats* stats); 56 | 57 | /** 58 | * Print memory leaks to console terminal 59 | * @ingroup mem 60 | */ 61 | CORE_API void mem_reportleaks(); 62 | 63 | /** 64 | * Allocate memory of requested size from the heap 65 | * @param size memory size (bytes) 66 | * @param source source file of memory allocation call 67 | * @param line line of memory allocation call 68 | * @param id custom memory id of allocated memory 69 | * @return allocated memory block 70 | * @ingroup mem 71 | */ 72 | CORE_API void* mem_alloc(size_t size, const char* source, uint line, uint id); 73 | CORE_API void* mem_realloc(void *p, size_t size, const char *source, uint line, uint id); 74 | /** 75 | * free alloacted memory from heap 76 | * @ingroup mem 77 | */ 78 | CORE_API void mem_free(void* ptr); 79 | /** 80 | * aligned heap allocation 81 | * @see mem_alloc @ingroup mem 82 | */ 83 | CORE_API void* mem_alignedalloc(size_t size, uint8 alignment, const char* source, 84 | uint line, uint id); 85 | CORE_API void* mem_alignedrealloc(void *p, size_t size, uint8 alignment, const char* source, 86 | uint line, uint id); 87 | /** 88 | * Aligned heap free 89 | * @see mem_free 90 | * @ingroup mem 91 | */ 92 | CORE_API void mem_alignedfree(void* ptr); 93 | 94 | /** 95 | * Set the maximum limit of heap memory allocation - overflow memory allocation calls will return NULL 96 | * @ingroup mem 97 | */ 98 | CORE_API void mem_setmaxlimit(size_t size); 99 | 100 | /** 101 | * Checks if memory limit is passed 102 | * @see mem_setmaxlimit @ingroup mem 103 | */ 104 | CORE_API int mem_isoverrun(); 105 | 106 | /** 107 | * Gets allocation size of certain memory Id 108 | * @return allocated memory id size (bytes) 109 | * @ingroup mem 110 | */ 111 | CORE_API size_t mem_sizebyid(uint id); 112 | 113 | /** 114 | * Gets allocated size of a memory block 115 | * @ingroup mem 116 | */ 117 | CORE_API size_t mem_size(void* ptr); 118 | /** 119 | * Gets aligned allocated memory block size 120 | * @ingroup mem 121 | */ 122 | CORE_API size_t mem_alignedsize(void* ptr); 123 | 124 | /** 125 | * Gets default global heap allocator 126 | * @ingroup alloc 127 | */ 128 | CORE_API struct allocator* mem_heap(); 129 | 130 | /** 131 | * Binds default heap allocator to specified allocator object 132 | * @ingroup alloc 133 | */ 134 | CORE_API void mem_heap_bindalloc(struct allocator *alloc); 135 | 136 | /** 137 | * @brief Applies padding to pointer and returns aligned pointer 138 | * @param ptr 139 | * @param alignment 140 | * @return 141 | * @ingroup alloc 142 | */ 143 | CORE_API void* mem_align_ptr(void *ptr, uint8 alignment); 144 | 145 | /** 146 | * Heap allocate macro 147 | * @param size requested memory size in bytes 148 | * @param id ID of the memory block 149 | * @ingroup mem 150 | */ 151 | #define ALLOC(size, id) mem_alloc((size), __FILE__, __LINE__, (id)) 152 | 153 | /** 154 | * Heap reallocate macro 155 | * @param ptr current allocated pointer, can be NULL 156 | * @param size requested memory size in bytes 157 | * @param id ID of the memory block 158 | * @ingroup mem 159 | */ 160 | #define REALLOC(ptr, size, id) mem_realloc((ptr), (size), __FILE__, __LINE__, (id)) 161 | 162 | /** 163 | * Aligned Heap allocate macro 164 | * @see ALLOC 165 | * @ingroup mem 166 | */ 167 | #define ALIGNED_ALLOC(size, id) mem_alignedalloc((size), _ALIGN_DEFAULT_, __FILE__, __LINE__, (id)) 168 | 169 | /** 170 | * Aligned Heap allocate macro 171 | * @see REALLOC 172 | * @ingroup mem 173 | */ 174 | #define ALIGNED_REALLOC(ptr, size, id) mem_alignedrealloc((ptr), (size), _ALIGN_DEFAULT_, __FILE__, __LINE__, (id)) 175 | 176 | /** 177 | * Free heap memory 178 | * @param ptr Pointer to allocated memory 179 | * @see ALLOC 180 | * @ingroup mem 181 | */ 182 | #define FREE(ptr) mem_free((ptr)) 183 | 184 | /** 185 | * Free aligned memory from heap 186 | * @param size Requested memory size in bytes 187 | * @param id ID of the memory block 188 | * @see ALIGNED_ALLOC 189 | * @ingroup mem 190 | */ 191 | #define ALIGNED_FREE(ptr) mem_alignedfree((ptr)) 192 | 193 | #if defined(_GNUC_) 194 | #define ALIGN16 __attribute__((aligned(16))) 195 | #elif defined(_MSVC_) 196 | #define ALIGN16 __declspec(align(16)) 197 | #endif 198 | 199 | #ifdef __cplusplus 200 | #include 201 | 202 | template 203 | T* mem_new(uint mem_id = 0) 204 | { 205 | void *ptr = ALLOC(sizeof(T), mem_id); 206 | if (ptr != NULL) 207 | return new(ptr) T(); 208 | return NULL; 209 | } 210 | 211 | template 212 | void mem_delete(T *t) 213 | { 214 | t->~T(); 215 | FREE(t); 216 | } 217 | 218 | template 219 | T* mem_new_aligned(uint mem_id = 0) 220 | { 221 | void *ptr = ALIGNED_ALLOC(sizeof(T), mem_id); 222 | if (ptr != NULL) 223 | return new(ptr) T(); 224 | return NULL; 225 | } 226 | 227 | template 228 | void mem_delete_aligned(T *t) 229 | { 230 | t->~T(); 231 | ALIGNED_FREE(t); 232 | } 233 | 234 | #endif 235 | 236 | #endif /* __MEMMGR_H__ */ 237 | --------------------------------------------------------------------------------