Skip to content

Instantly share code, notes, and snippets.

@fouric
Last active September 6, 2019 15:20
Show Gist options
  • Save fouric/dacbd9a56245673a2c65fbf086d2dbbb to your computer and use it in GitHub Desktop.
Save fouric/dacbd9a56245673a2c65fbf086d2dbbb to your computer and use it in GitHub Desktop.
nuklear (https://github.com/vurtun/nuklear) is a single-file immediate-mode GUI library written in ANSI C that has been surprisingly popular in the Common Lisp game development world recently (although by "surprisingly popular" I mean "more than three people have been talking about it")
Currently, two people are working on CL bindings for nuklear: baggers (with the cl-nuklear bindings (https://github.com/cbaggers/cl-nuklear) and CEPL backend) and borodust (with cl-bodge integration with said bindings).
However, nuklear doesn't appear to have any particularly strong ties to C.
That is, (1) it doesn't have insane (BLAS-level) speed requirements and (2) it doesn't rely on any particularly low-level features that can't be achieved in CL through moderate use of libraries.
Aside from "it's already in C", the two justifications above are the only reason to write or use things in C.
cloc in nuklear/src yields 19k lines of code. As long as nuklear follows a straightforward design and doesn't do any insane pointer magic, it should be very easy (if time-consuming) to port it to CL almost verbatim.
Now, while I have magpie-brain, and might not spend any more time on this than the words I have already written, it doesn't hurt to record my thoughts for later use, should I continue the project
I'm going in to nuklear/src and looking for "fundamental" files. There are a bunch of files that are clearly "non-core", like nuklear_popup.c and nuklear_sscrollbar.c, and we don't care about those right now - we just want to get the "core" working.
Actually, now that I think about it, I could probably get a working framework after porting far less than those 19k lines, as a good chunk of the code is probbaly just building on the core to implement all the different GUI widgets.
Let's look at nuklear_draw.c. At the top, it references nuklear.h and nuklear_internal.h.
Both of those look pretty important, let's go there - but only after making the observation that most of the functions in nuklear_draw.c are prefixed with "NK_LIB".
Upon inspection of nuklear.h, NK_LIB turns out to be a preprocessor constant that either resolves to `static` or `extern` depending on whether nuklear is compiled in single-file mode or not. This is a no-op in CL.
nuklear.h turns out to be the largest file in src, at 253kb and 2kloc. There are a very large number of declarations (mostly no-ops in CL), enums (just use symbols), and documentation comments (can be partially copied over). Actually, 3k lines in the file are comments, compared to 2k lines of code.
It might be beneficial to take a nuklear demo, port it to CL, stub all of the necessary functions, and then begin filling out the functionality one function at a time.
The calculator (https://github.com/vurtun/nuklear/blob/master/demo/calculator.c) seems to be the smallest application, how about that one? Oh, and then you need a backend - let's go with sdl2+opengl3. That adds main.c and nuklear_sdl_gl3.h files, but the total code size is strictly under 1kloc.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment