From 7d9bf6cfa18b360de0326f927a43d3f7826a78d2 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 26 Jan 2021 10:48:24 +0100 Subject: Update README --- README.md | 120 +++----------------------------------------------------------- 1 file changed, 4 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index 56d8b9d..524b147 100644 --- a/README.md +++ b/README.md @@ -1,118 +1,6 @@ -# Micro Interactive C Framework (MIC) +# Micro Interactive C Framework (MIC): OpenGL example -MIC is a tiny (<300 cloc) framework to boostrap interactive C projects. -Application code can be dynamically reloaded upon compilation, allowing C to be -used as a pseudo-scripting language. This property can be very useful when -developing, but might not be always desirable for a final release, for this -reason, static compilation can be selected as a make target when needed. The -main limitation of hot code reload is that global state can't be stored in the -main app code, but the framework is designed so the state is passed around when -needed and is always accessible for the relevant functions. +This is an example of using the MIC framework for bootstrapping an OpenGL +application. For more details head to [the article][article]. -This framework can be easily extended to work with multiple platforms. However, -hot code reload will only be available for platforms that support dynamic -linking. For the moment, only POSIX compliant platforms are supported but -Windows is a target for the near future. - -Remember that MIC is only a base, you can (and should) modify anything in here -to adapt it to your particular project. - -## Example usage - -Compile and execute the program: - -``` -make && ./build/app -``` - -While the application is running, make changes to the `src/app.c`. For example, -change the `app_step` function from: - -``` -static inline bool -app_step(AppState *state, PlatformAPI platform) { - (void)state; // Unused parameter. - platform.log("STEP"); - platform.sleep(100000); - return true; -} -``` - -To: - -``` -static inline bool -app_step(AppState *state, PlatformAPI platform) { - (void)state; // Unused parameter. - platform.log("Hello world!"); - platform.sleep(100000); - return true; -} -``` - -In another terminal (or using your editor of choice), recompile the program: - -``` -make -``` - -The changes should take effect in the running application. - -## Implementation details - -This framework offers two APIs for managing system resources and executing -application logic. The `PlatformAPI` is described in `src/platform.h` and it's -tasked with manage the resources of the platform and/or operating system. For -example, opening/reading files, allocating memory, logging, etc. To support -a new platform it is sufficient to implement the functions described on the API -and make sure to select such platform at compile time. Additionally, the -following internal functions must be implemented for static and dynamic linking: - -``` -// Load the dynamic library and initialize application. Returns the success or -// failure of this operation. -static bool _app_init(AppAPI *api, AppState *state, PlatformAPI platform); - -// This function reloads the application code from the dynamic library, -// returning `true` if the AppAPI is ready to be used. -static bool _app_reload(); - -// Cleanup resources before exit. -static void _app_destroy(AppAPI *api, AppState *state, PlatformAPI platform); -``` - -The `AppAPI`, described in `src/app.h` and handles app initialization and -destruction, it contains the behaviour in the event of hot code reloading as -well as the main step function. The `init` function typically will be tasked -with initial allocation of resources. The duty of `reload` and `unload` is -application dependent, for example, we might wish to re-compile the shader -programs or reload geometry/sprites when we make modifications to the main -application code. The `step` function is called in every iteration of the loop, -and is where the bulk of the logic will likely be. - -The application state is stored in a unique `AppState` structure. MIC has been -architected so that the state and platform functions are available in the -previously mentioned `AppAPI` functions. `AppState` can contain whatever state -is needed and will be persistent when re-compiling. The only limitation is that -if the `AppState` structure changes, the application must be restarted, as the -stored state will become invalid. This can be circumvented by pre-allocating -some memory that can then be partitioned with a pool allocator to suit the -application needs. This design is also conducive for saving state data by simply -serializing the `AppState` structure. - -## Credits - -I initially discovered the hot code reloading trick when watching [Casey -Muratori's][casey] [Handmade Hero][handmade] series. It blew my mind! However, -the code he presented was focused solely on Windows and I never end up trying it -myself. Some years later I tried to find a way of making this work in Mac/Linux -when I came across [Chris Wellons'][skeeto] take on this problem with a clever -function pointer API in his [interactive c demo][interac-c-demo] page. This -framework uses a lot of the ideas he presents there, as you can clearly see if -you look at [his code][interac-c-demo]. - -[casey]: https://caseymuratori.com -[handmade]: https://handmadehero.org -[skeeto]: https://nullprogram.com -[interac-c-demo]: https://nullprogram.com/blog/2014/12/23/ -[interac-c-demo-github]: https://github.com/skeeto/interactive-c-demo +[article]: https://badd10de.dev/posts/mic-framework-opengl-example/ -- cgit v1.2.1