{"id":13605923,"url":"https://github.com/Tremus/xhl","last_synced_at":"2025-04-12T05:35:12.034Z","repository":{"id":191836421,"uuid":"633247616","full_name":"Tremus/xhl","owner":"Tremus","description":"Single header libraries \u0026 utilities","archived":false,"fork":false,"pushed_at":"2024-09-15T01:45:21.000Z","size":134,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-09-15T07:52:09.626Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tremus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-27T05:10:34.000Z","updated_at":"2024-09-15T01:45:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"88edf625-73bc-4447-b832-296f83583b37","html_url":"https://github.com/Tremus/xhl","commit_stats":null,"previous_names":["tremus/xhl"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tremus%2Fxhl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tremus%2Fxhl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tremus%2Fxhl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tremus%2Fxhl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tremus","download_url":"https://codeload.github.com/Tremus/xhl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223498113,"owners_count":17155264,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T19:01:04.267Z","updated_at":"2024-11-07T10:31:33.944Z","avatar_url":"https://github.com/Tremus.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"# xhl\n\nStands for:\n\n-   xingle header libraries\n-   xtendable header libraries\n-   sexy header libraries\n-   extreme header libraries\n\n[STB-Style](https://github.com/nothings/stb/blob/master/docs/stb_howto.txt) headers\n\n### [alloc.h](include/xhl/alloc.h)\n\nWraps `malloc`, calling `exit(ENOMEM)` if `NULL` is returned. Additionally tracks number of `xmalloc` calls in `DEBUG` to help spot memory leaks.\n\n```c\n#include \u003cxhl/alloc.h\u003e\nint main() {\n    // will exit with ENOMEM\n    int* nums = xmalloc(1LLU \u003c\u003c 63);\n    // unreachable\n    nums = xrealloc(nums, 2);\n    xfree(nums);\n    return 0;\n}\n```\n\n### [array.h](include/xhl/array.h)\n\nDynamic array, type agnostic. Based on [stb_ds.h](https://github.com/nothings/stb/blob/master/stb_ds.h) by Sean Barrett.\n\nSupports custom allocator. Relloc calls are inlined in case you need to track where they're called from.\n\n```c\n#define XARR_REALLOC(ptr, size) (printf(\"realloc: %p, (%uz) - %s:%d\\n\", (ptr), (size), __FILE__, __LINE__), realloc(ptr, size))\n#define XARR_FREE(ptr) (printf(\"free: %p - %s:%d\\n\", p, __FILE__, __LINE__), free(ptr))\n#include \u003cxhl/array.h\u003e\n\nint* nums = NULL;\nfor (int i = 0; i \u003c 10; i++)\n    xarr_push(nums, 1);\nxarr_delete(nums, 8);\nxarr_delete(nums, 5);\nxarr_insert(nums, 2, 69);\nxarr_free(nums);\n```\n\n### [component.h](include/xhl/component.h)\n\nBackbone for a retained mode GUI. Contains base widget struct and all of the logic for sending mouse and keyboard events from your to components in your heirarchy. Use this to write your own widgets which respond to events. Pair with your desired graphics engine.\n\nBase component is optimised to be very small.\n\n```c\n// gui.c\nstruct GUI {\n    xcomp_root root;\n    xcomp_component top;\n    xcomp_component* children[1];\n    xcomp_component child_btn1;\n}\nvoid handle_events_btn1(struct xcomp_component* comp uint32_t e, xcomp_event_data)\n{\n    if (e == XCOMP_EVENT_MOUSE_ENTER)\n    {\n        GUI* gui = (GUI*)comp-\u003edata;\n        ... // eg. change mouse cursor\n    }\n}\nvoid init_gui(GUI* gui)\n{\n    gui-\u003eroot.main = \u0026gui-\u003etop;\n    // Fixed size array, avoids additional allocations\n    gui-\u003eroot.top.children = gui-\u003echildren;\n    xcomp_add_child(\u0026gui-\u003eroot.top, \u0026gui-\u003eroot.child_btn1);\n    gui-\u003echild_btn1.event_handler = handle_events_btn1;\n    gui-\u003echild_btn1.data = gui;\n}\n// os_window_events.c\n...\ncase MOUSE_MOVE:\n    xcomp_send_mouse_position(\u0026gui-\u003eroot, x, y);\ncase MOUSE_DOWN:\n    xcomp_send_mouse_down(\u0026gui-\u003eroot, x, y);\ncase MOUSE_UP:\n    xcomp_send_mouse_up(\u0026gui-\u003eroot, x, y);\n... // etc\n```\n\n### [debug.h](include/xhl/debug.h)\n\nSimple macros for pausing your debugger.\n\n```c\nxassert(2 + 2 == 5); // pause\n```\n\n### [files.h](include/xhl/files.h)\n\nImperitive file reading \u0026 writing. Paths are expected to be UTF8. Handles platform specific conversions\n\n```c\n// Build file path (no allocs!)\nchar path[1024];\nstatic const char* filename = XFILES_DIR_STR \"file.txt\"; // Win \\\\file.txt, Posix /file.txt\nxfiles_get_user_directory(path, sizeof(path), XFILES_USER_DIRECTORY_DESKTOP);\nstrncat(path, filename, sizeof(path) - strlen(path) - 1);\n// Write\nassert(!xfiles_exists(path));\nstatic const char* writebuf  = \"Hello World!\";\nxfiles_write(path, writebuf, strlen(writebuf));\nassert(xfiles_exists(path));\n// Read (allocates memory!)\nchar*  readbuf    = NULL;\nsize_t readbuflen = 0;\nxfiles_read(path, (void**)\u0026readbuf, \u0026readbuflen);\nprintf(\"Contents: %.*s\\n\", (int)(readbuflen), readbuf);\nfree(readbuf);\n// Move to OS bin / trash\nxfiles_trash(path);\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTremus%2Fxhl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTremus%2Fxhl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTremus%2Fxhl/lists"}