Skip to content

Tremus/xhl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

xhl

Stands for:

  • xingle header libraries
  • xtendable header libraries
  • sexy header libraries
  • extreme header libraries

STB-Style headers

Wraps malloc, calling exit(ENOMEM) if NULL is returned. Additionally tracks number of xmalloc calls in DEBUG to help spot memory leaks.

#include <xhl/alloc.h>
int main() {
    // will exit with ENOMEM
    int* nums = xmalloc(1LLU << 63);
    // unreachable
    nums = xrealloc(nums, 2);
    xfree(nums);
    return 0;
}

Dynamic array, type agnostic. Based on stb_ds.h by Sean Barrett.

Supports custom allocator. Relloc calls are inlined in case you need to track where they're called from.

#define XARR_REALLOC(ptr, size) (printf("realloc: %p, (%uz) - %s:%d\n", (ptr), (size), __FILE__, __LINE__), realloc(ptr, size))
#define XARR_FREE(ptr) (printf("free: %p - %s:%d\n", p, __FILE__, __LINE__), free(ptr))
#include <xhl/array.h>

int* nums = NULL;
for (int i = 0; i < 10; i++)
    xarr_push(nums, 1);
xarr_delete(nums, 8);
xarr_delete(nums, 5);
xarr_insert(nums, 2, 69);
xarr_free(nums);

Backbone 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.

Base component is optimised to be very small.

// gui.c
struct GUI {
    xcomp_root root;
    xcomp_component top;
    xcomp_component* children[1];
    xcomp_component child_btn1;
}
void handle_events_btn1(struct xcomp_component* comp uint32_t e, xcomp_event_data)
{
    if (e == XCOMP_EVENT_MOUSE_ENTER)
    {
        GUI* gui = (GUI*)comp->data;
        ... // eg. change mouse cursor
    }
}
void init_gui(GUI* gui)
{
    gui->root.main = &gui->top;
    // Fixed size array, avoids additional allocations
    gui->root.top.children = gui->children;
    xcomp_add_child(&gui->root.top, &gui->root.child_btn1);
    gui->child_btn1.event_handler = handle_events_btn1;
    gui->child_btn1.data = gui;
}
// os_window_events.c
...
case MOUSE_MOVE:
    xcomp_send_mouse_position(&gui->root, x, y);
case MOUSE_DOWN:
    xcomp_send_mouse_down(&gui->root, x, y);
case MOUSE_UP:
    xcomp_send_mouse_up(&gui->root, x, y);
... // etc

Simple macros for pausing your debugger.

xassert(2 + 2 == 5); // pause

Imperitive file reading & writing. Paths are expected to be UTF8. Handles platform specific conversions

// Build file path (no allocs!)
char path[1024];
static const char* filename = XFILES_DIR_STR "file.txt"; // Win \\file.txt, Posix /file.txt
xfiles_get_user_directory(path, sizeof(path), XFILES_USER_DIRECTORY_DESKTOP);
strncat(path, filename, sizeof(path) - strlen(path) - 1);
// Write
assert(!xfiles_exists(path));
static const char* writebuf  = "Hello World!";
xfiles_write(path, writebuf, strlen(writebuf));
assert(xfiles_exists(path));
// Read (allocates memory!)
char*  readbuf    = NULL;
size_t readbuflen = 0;
xfiles_read(path, (void**)&readbuf, &readbuflen);
printf("Contents: %.*s\n", (int)(readbuflen), readbuf);
free(readbuf);
// Move to OS bin / trash
xfiles_trash(path);

About

Single header libraries & utilities

Resources

License

Stars

Watchers

Forks