Simple Decision Tables
Last updated on
Deep nested branches can get quite ugly to read and even follow, I find decision tables can be a good technique to cleaning up some code. It also a good way to make code data centeric. Wiki has an article on it.
Here is a simple/contrived example.
#include <stdint.h>
#include <stdio.h>
int
main() {
/* flags that represent some data */
uint32_t renderable_bit = 1 << 0;
uint32_t input_bit = 1 << 1;
uint32_t menu_bit = 1 << 2;
uint32_t player_bit = 1 << 3;
/* conditions */
uint32_t should_render = renderable_bit;
uint32_t should_update_player = player_bit | input_bit;
uint32_t should_play_menu_audio = menu_bit | input_bit;
/* world data - in the real world this will be runtime */
struct renderable {int i;};
struct renderable renderables[1];
struct player {int i;};
struct player players[1];
struct menu {int i;};
struct menu menu_items[0];
struct input {int i;};
struct input inputs[1];
/* world state */
uint32_t world = 0;
world |= (sizeof(renderables) ? renderable_bit : 0);
world |= (sizeof(players) ? player_bit : 0);
world |= (sizeof(menu_items) ? menu_bit : 0);
world |= (sizeof(inputs) ? input_bit : 0);
/* process world */
if((world & should_update_player) == should_update_player) {
printf("update_player();\n");
}
if((world & should_render) == should_render) {
printf("render();\n");
}
if((world & should_play_menu_audio) == should_play_menu_audio) {
printf("play_menu_audio();\n");
}
}
build and go
cc simple_decision_table.c && ./a.out
Outputs
update_player();
render();
As you can see we don’t play any audio because the bit never got set. I have in the past used to this to know what tasks to send off to the thread pool.