Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify Command Lists #55

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions demo/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ else
GLFLAG="-lGL"
fi

CFLAGS="-I../src -Wall -std=c11 -pedantic `sdl2-config --libs` $GLFLAG -lm -O3 -g"

gcc main.c renderer.c ../src/microui.c $CFLAGS
CFLAGS="-I../src -Wall -std=c11 -pedantic `sdl2-config --libs` $GLFLAG -lm -O0 -g"

gcc -o demo main.c renderer.c ../src/microui.c $CFLAGS
2 changes: 0 additions & 2 deletions demo/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,5 +291,3 @@ int main(int argc, char **argv) {

return 0;
}


69 changes: 42 additions & 27 deletions src/microui.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ void mu_begin(mu_Context *ctx) {
expect(ctx->text_width && ctx->text_height);
ctx->command_list.idx = 0;
ctx->root_list.idx = 0;
ctx->text_stack.idx = 0;
ctx->scroll_target = NULL;
ctx->hover_root = ctx->next_hover_root;
ctx->next_hover_root = NULL;
Expand Down Expand Up @@ -197,14 +198,18 @@ void mu_end(mu_Context *ctx) {
** otherwise set the previous container's tail to jump to this one */
if (i == 0) {
mu_Command *cmd = (mu_Command*) ctx->command_list.items;
cmd->jump.dst = (char*) cnt->head + sizeof(mu_JumpCommand);
expect(cmd->type == MU_COMMAND_JUMP);
cmd->jump.dst_idx = cnt->head_idx + 1;
expect(cmd->jump.dst_idx < MU_COMMANDLIST_SIZE);
} else {
mu_Container *prev = ctx->root_list.items[i - 1];
prev->tail->jump.dst = (char*) cnt->head + sizeof(mu_JumpCommand);
ctx->command_list.items[prev->tail_idx].jump.dst_idx = cnt->head_idx + 1;
}
/* make the last container's tail jump to the end of command list */
if (i == n - 1) {
cnt->tail->jump.dst = ctx->command_list.items + ctx->command_list.idx;
expect(cnt->tail_idx < MU_COMMANDLIST_SIZE);
expect(ctx->command_list.items[cnt->tail_idx].type == MU_COMMAND_JUMP);
ctx->command_list.items[cnt->tail_idx].jump.dst_idx = ctx->command_list.idx;
}
}
}
Expand Down Expand Up @@ -322,6 +327,8 @@ static mu_Container* get_container(mu_Context *ctx, mu_Id id, int opt) {
idx = mu_pool_init(ctx, ctx->container_pool, MU_CONTAINERPOOL_SIZE, id);
cnt = &ctx->containers[idx];
memset(cnt, 0, sizeof(*cnt));
cnt->head_idx = -1;
cnt->tail_idx = -1;
cnt->open = 1;
mu_bring_to_front(ctx, cnt);
return cnt;
Expand Down Expand Up @@ -424,41 +431,50 @@ void mu_input_text(mu_Context *ctx, const char *text) {
** commandlist
**============================================================================*/

mu_Command* mu_push_command(mu_Context *ctx, int type, int size) {
mu_Command *cmd = (mu_Command*) (ctx->command_list.items + ctx->command_list.idx);
expect(ctx->command_list.idx + size < MU_COMMANDLIST_SIZE);
mu_Command* mu_push_command(mu_Context *ctx, int type) {
mu_Command *cmd = &ctx->command_list.items[ctx->command_list.idx];
expect(ctx->command_list.idx < MU_COMMANDLIST_SIZE);
cmd->base.type = type;
cmd->base.size = size;
ctx->command_list.idx += size;
ctx->command_list.idx += 1;
return cmd;
}

char* mu_push_text(mu_Context* ctx, const char* str, size_t len) {
char* str_start = &ctx->text_stack.items[ctx->text_stack.idx];
expect(ctx->text_stack.idx + len + 1 < MU_CONTEXT_TEXT_SIZE);

memcpy(str_start, str, len);
str_start[len] = '\0';
ctx->text_stack.idx += len + 1;
return str_start;
}

int mu_next_command(mu_Context *ctx, mu_Command **cmd) {
if (*cmd) {
*cmd = (mu_Command*) (((char*) *cmd) + (*cmd)->base.size);
*cmd = *cmd + 1;
} else {
*cmd = (mu_Command*) ctx->command_list.items;
*cmd = ctx->command_list.items;
}
while ((char*) *cmd != ctx->command_list.items + ctx->command_list.idx) {
while (*cmd != &ctx->command_list.items[ctx->command_list.idx]) {
if ((*cmd)->type != MU_COMMAND_JUMP) { return 1; }
*cmd = (*cmd)->jump.dst;
*cmd = &ctx->command_list.items[(*cmd)->jump.dst_idx];
}
return 0;
}


static mu_Command* push_jump(mu_Context *ctx, mu_Command *dst) {
static int push_jump(mu_Context *ctx, int dst_idx) {
mu_Command *cmd;
cmd = mu_push_command(ctx, MU_COMMAND_JUMP, sizeof(mu_JumpCommand));
cmd->jump.dst = dst;
return cmd;
cmd = mu_push_command(ctx, MU_COMMAND_JUMP);
cmd->jump.dst_idx = dst_idx;
expect(cmd == &ctx->command_list.items[ctx->command_list.idx - 1]);
return ctx->command_list.idx - 1;
}


void mu_set_clip(mu_Context *ctx, mu_Rect rect) {
mu_Command *cmd;
cmd = mu_push_command(ctx, MU_COMMAND_CLIP, sizeof(mu_ClipCommand));
cmd = mu_push_command(ctx, MU_COMMAND_CLIP);
cmd->clip.rect = rect;
}

Expand All @@ -467,7 +483,7 @@ void mu_draw_rect(mu_Context *ctx, mu_Rect rect, mu_Color color) {
mu_Command *cmd;
rect = intersect_rects(rect, mu_get_clip_rect(ctx));
if (rect.w > 0 && rect.h > 0) {
cmd = mu_push_command(ctx, MU_COMMAND_RECT, sizeof(mu_RectCommand));
cmd = mu_push_command(ctx, MU_COMMAND_RECT);
cmd->rect.rect = rect;
cmd->rect.color = color;
}
Expand All @@ -493,9 +509,9 @@ void mu_draw_text(mu_Context *ctx, mu_Font font, const char *str, int len,
if (clipped == MU_CLIP_PART) { mu_set_clip(ctx, mu_get_clip_rect(ctx)); }
/* add command */
if (len < 0) { len = strlen(str); }
cmd = mu_push_command(ctx, MU_COMMAND_TEXT, sizeof(mu_TextCommand) + len);
memcpy(cmd->text.str, str, len);
cmd->text.str[len] = '\0';
char* str_start = mu_push_text(ctx, str, len);
cmd = mu_push_command(ctx, MU_COMMAND_TEXT);
cmd->text.str = str_start;
cmd->text.pos = pos;
cmd->text.color = color;
cmd->text.font = font;
Expand All @@ -511,7 +527,7 @@ void mu_draw_icon(mu_Context *ctx, int id, mu_Rect rect, mu_Color color) {
if (clipped == MU_CLIP_ALL ) { return; }
if (clipped == MU_CLIP_PART) { mu_set_clip(ctx, mu_get_clip_rect(ctx)); }
/* do icon command */
cmd = mu_push_command(ctx, MU_COMMAND_ICON, sizeof(mu_IconCommand));
cmd = mu_push_command(ctx, MU_COMMAND_ICON);
cmd->icon.id = id;
cmd->icon.rect = rect;
cmd->icon.color = color;
Expand Down Expand Up @@ -634,7 +650,7 @@ static int in_hover_root(mu_Context *ctx) {
if (ctx->container_stack.items[i] == ctx->hover_root) { return 1; }
/* only root containers have their `head` field set; stop searching if we've
** reached the current root container */
if (ctx->container_stack.items[i]->head) { break; }
if (ctx->container_stack.items[i]->head_idx != -1) { break; }
}
return 0;
}
Expand Down Expand Up @@ -984,7 +1000,6 @@ void mu_end_treenode(mu_Context *ctx) {
mu_pop_id(ctx);
}


#define scrollbar(ctx, cnt, b, cs, x, y, w, h) \
do { \
/* only add scrollbar if content size is larger than body */ \
Expand Down Expand Up @@ -1053,7 +1068,7 @@ static void begin_root_container(mu_Context *ctx, mu_Container *cnt) {
push(ctx->container_stack, cnt);
/* push container to roots list and push head command */
push(ctx->root_list, cnt);
cnt->head = push_jump(ctx, NULL);
cnt->head_idx = push_jump(ctx, -1);
/* set as hover root if the mouse is overlapping this container and it has a
** higher zindex than the current hover root */
if (rect_overlaps_vec2(cnt->rect, ctx->mouse_pos) &&
Expand All @@ -1072,8 +1087,8 @@ static void end_root_container(mu_Context *ctx) {
/* push tail 'goto' jump command and set head 'skip' command. the final steps
** on initing these are done in mu_end() */
mu_Container *cnt = mu_get_current_container(ctx);
cnt->tail = push_jump(ctx, NULL);
cnt->head->jump.dst = ctx->command_list.items + ctx->command_list.idx;
cnt->tail_idx = push_jump(ctx, -1);
ctx->command_list.items[cnt->head_idx].jump.dst_idx = ctx->command_list.idx;
/* pop base clip rect and container */
mu_pop_clip_rect(ctx);
pop_container(ctx);
Expand Down
22 changes: 13 additions & 9 deletions src/microui.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

#define MU_VERSION "2.01"

#define MU_COMMANDLIST_SIZE (256 * 1024)
#define MU_CONTEXT_TEXT_SIZE 65536
#define MU_COMMANDLIST_SIZE 4096
#define MU_ROOTLIST_SIZE 32
#define MU_CONTAINERSTACK_SIZE 32
#define MU_CLIPSTACK_SIZE 32
Expand Down Expand Up @@ -116,22 +117,24 @@ typedef struct { int x, y, w, h; } mu_Rect;
typedef struct { unsigned char r, g, b, a; } mu_Color;
typedef struct { mu_Id id; int last_update; } mu_PoolItem;

typedef struct { int type, size; } mu_BaseCommand;
typedef struct { mu_BaseCommand base; void *dst; } mu_JumpCommand;
typedef union mu_Command mu_Command;

typedef struct { int type; } mu_BaseCommand;
typedef struct { mu_BaseCommand base; int dst_idx; } mu_JumpCommand;
typedef struct { mu_BaseCommand base; mu_Rect rect; } mu_ClipCommand;
typedef struct { mu_BaseCommand base; mu_Rect rect; mu_Color color; } mu_RectCommand;
typedef struct { mu_BaseCommand base; mu_Font font; mu_Vec2 pos; mu_Color color; char str[1]; } mu_TextCommand;
typedef struct { mu_BaseCommand base; mu_Font font; mu_Vec2 pos; mu_Color color; char* str; } mu_TextCommand;
typedef struct { mu_BaseCommand base; mu_Rect rect; int id; mu_Color color; } mu_IconCommand;

typedef union {
union mu_Command {
int type;
mu_BaseCommand base;
mu_JumpCommand jump;
mu_ClipCommand clip;
mu_RectCommand rect;
mu_TextCommand text;
mu_IconCommand icon;
} mu_Command;
};

typedef struct {
mu_Rect body;
Expand All @@ -148,7 +151,7 @@ typedef struct {
} mu_Layout;

typedef struct {
mu_Command *head, *tail;
int head_idx, tail_idx;
mu_Rect rect;
mu_Rect body;
mu_Vec2 content_size;
Expand Down Expand Up @@ -190,12 +193,13 @@ struct mu_Context {
char number_edit_buf[MU_MAX_FMT];
mu_Id number_edit;
/* stacks */
mu_stack(char, MU_COMMANDLIST_SIZE) command_list;
mu_stack(mu_Command, MU_COMMANDLIST_SIZE) command_list;
mu_stack(mu_Container*, MU_ROOTLIST_SIZE) root_list;
mu_stack(mu_Container*, MU_CONTAINERSTACK_SIZE) container_stack;
mu_stack(mu_Rect, MU_CLIPSTACK_SIZE) clip_stack;
mu_stack(mu_Id, MU_IDSTACK_SIZE) id_stack;
mu_stack(mu_Layout, MU_LAYOUTSTACK_SIZE) layout_stack;
mu_stack(char, MU_CONTEXT_TEXT_SIZE) text_stack;
/* retained state pools */
mu_PoolItem container_pool[MU_CONTAINERPOOL_SIZE];
mu_Container containers[MU_CONTAINERPOOL_SIZE];
Expand Down Expand Up @@ -244,7 +248,7 @@ void mu_input_keydown(mu_Context *ctx, int key);
void mu_input_keyup(mu_Context *ctx, int key);
void mu_input_text(mu_Context *ctx, const char *text);

mu_Command* mu_push_command(mu_Context *ctx, int type, int size);
mu_Command* mu_push_command(mu_Context *ctx, int type);
int mu_next_command(mu_Context *ctx, mu_Command **cmd);
void mu_set_clip(mu_Context *ctx, mu_Rect rect);
void mu_draw_rect(mu_Context *ctx, mu_Rect rect, mu_Color color);
Expand Down