summaryrefslogtreecommitdiff
path: root/src/dged
diff options
context:
space:
mode:
Diffstat (limited to 'src/dged')
-rw-r--r--src/dged/buffer.c99
-rw-r--r--src/dged/buffer.h22
-rw-r--r--src/dged/buffer_view.c51
-rw-r--r--src/dged/buffer_view.h5
-rw-r--r--src/dged/display.c7
-rw-r--r--src/dged/lang.c22
-rw-r--r--src/dged/s8.c25
-rw-r--r--src/dged/s8.h18
-rw-r--r--src/dged/syntax.c20
-rw-r--r--src/dged/text.c1
-rw-r--r--src/dged/timers.c95
-rw-r--r--src/dged/timers.h21
-rw-r--r--src/dged/window.c6
-rw-r--r--src/dged/window.h2
14 files changed, 344 insertions, 50 deletions
diff --git a/src/dged/buffer.c b/src/dged/buffer.c
index bfa0010..d25297f 100644
--- a/src/dged/buffer.c
+++ b/src/dged/buffer.c
@@ -7,9 +7,11 @@
#include "minibuffer.h"
#include "path.h"
#include "reactor.h"
+#include "s8.h"
#include "settings.h"
#include "utf8.h"
+#include <assert.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdbool.h>
@@ -680,7 +682,7 @@ struct location buffer_newline(struct buffer *buffer, struct location at) {
return buffer_add(buffer, at, (uint8_t *)"\n", 1);
}
-struct location buffer_indent(struct buffer *buffer, struct location at) {
+static uint32_t get_tab_width(struct buffer *buffer) {
struct setting *tw = lang_setting(&buffer->lang, "tab-width");
if (tw == NULL) {
tw = settings_get("editor.tab-width");
@@ -690,8 +692,39 @@ struct location buffer_indent(struct buffer *buffer, struct location at) {
if (tw != NULL && tw->value.type == Setting_Number) {
tab_width = tw->value.number_value;
}
- return buffer_add(buffer, at, (uint8_t *)" ",
- tab_width > 16 ? 16 : tab_width);
+ return tab_width;
+}
+
+static bool use_tabs(struct buffer *buffer) {
+ struct setting *ut = lang_setting(&buffer->lang, "use-tabs");
+ if (ut == NULL) {
+ ut = settings_get("editor.use-tabs");
+ }
+
+ bool use_tabs = false;
+ if (ut != NULL && ut->value.type == Setting_Bool) {
+ use_tabs = ut->value.bool_value;
+ }
+
+ return use_tabs;
+}
+
+static struct location do_indent(struct buffer *buffer, struct location at,
+ uint32_t tab_width, bool use_tabs) {
+ if (use_tabs) {
+ return buffer_add(buffer, at, (uint8_t *)"\t", 1);
+ } else {
+ return buffer_add(buffer, at, (uint8_t *)" ",
+ tab_width > 16 ? 16 : tab_width);
+ }
+}
+
+struct location buffer_indent(struct buffer *buffer, struct location at) {
+ return do_indent(buffer, at, get_tab_width(buffer), use_tabs(buffer));
+}
+
+struct location buffer_indent_alt(struct buffer *buffer, struct location at) {
+ return do_indent(buffer, at, get_tab_width(buffer), !use_tabs(buffer));
}
struct location buffer_undo(struct buffer *buffer, struct location dot) {
@@ -1160,3 +1193,63 @@ void buffer_get_text_properties(struct buffer *buffer, struct location location,
void buffer_clear_text_properties(struct buffer *buffer) {
text_clear_properties(buffer->text);
}
+
+static int compare_lines(const void *l1, const void *l2) {
+ return s8cmp(*(const struct s8 *)l1, *(const struct s8 *)l2);
+}
+
+void buffer_sort_lines(struct buffer *buffer, uint32_t start_line,
+ uint32_t end_line) {
+ const uint32_t nlines = text_num_lines(buffer->text);
+ if (nlines == 0) {
+ return;
+ }
+
+ uint32_t start = start_line >= nlines ? nlines - 1 : start_line;
+ uint32_t end = end_line >= nlines ? nlines - 1 : end_line;
+
+ if (end <= start) {
+ return;
+ }
+
+ const uint32_t ntosort = end - start + 1;
+
+ struct region region =
+ region_new((struct location){.line = start, .col = 0},
+ (struct location){.line = end + 1, .col = 0});
+
+ struct s8 *lines = (struct s8 *)malloc(sizeof(struct s8) * ntosort);
+ struct text_chunk txt =
+ text_get_region(buffer->text, region.begin.line, region.begin.col,
+ region.end.line, region.end.col);
+
+ uint32_t line_start = 0;
+ uint32_t curr_line = 0;
+ for (uint32_t bytei = 0; bytei < txt.nbytes; ++bytei) {
+ if (txt.text[bytei] == '\n') {
+ lines[curr_line] =
+ (struct s8){.s = &txt.text[line_start], .l = bytei - line_start + 1};
+
+ ++curr_line;
+ line_start = bytei + 1;
+ }
+ }
+
+ qsort(lines, ntosort, sizeof(struct s8), compare_lines);
+
+ struct location at = buffer_delete(buffer, region);
+ for (uint32_t linei = 0; linei < ntosort; ++linei) {
+ struct s8 line = lines[linei];
+ at = buffer_add(buffer, at, (uint8_t *)line.s, line.l);
+ }
+
+ // if the last line we are sorting is the last line in the buffer,
+ // we have added one extra unwanted newline
+ if (end == nlines - 1) {
+ strip_final_newline(buffer);
+ }
+
+ if (txt.allocated) {
+ free(txt.text);
+ }
+}
diff --git a/src/dged/buffer.h b/src/dged/buffer.h
index 3cb8d03..496086a 100644
--- a/src/dged/buffer.h
+++ b/src/dged/buffer.h
@@ -312,6 +312,18 @@ struct location buffer_newline(struct buffer *buffer, struct location at);
struct location buffer_indent(struct buffer *buffer, struct location at);
/**
+ * Insert alternative indentation in the buffer.
+ *
+ * Alternative indentation is spaces if it is normally using tabs
+ * and vice versa.
+ *
+ * @param [in] buffer The buffer to indent in.
+ * @param [in] at The location to insert indentation at.
+ * @returns The position after indenting.
+ */
+struct location buffer_indent_alt(struct buffer *buffer, struct location at);
+
+/**
* Undo the last operation in the buffer.
*
* @param [in] buffer The buffer to undo in.
@@ -530,4 +542,14 @@ void buffer_render(struct buffer *buffer, struct buffer_render_params *params);
uint32_t visual_string_width(uint8_t *txt, uint32_t len, uint32_t start_col,
uint32_t end_col);
+/**
+ * Sort lines in a buffer alphabetically.
+ *
+ * @param [in] buffer The buffer to sort lines in.
+ * @param [in] start_line The first line to sort.
+ * @param [in] end_line The last line to sort.
+ */
+void buffer_sort_lines(struct buffer *buffer, uint32_t start_line,
+ uint32_t end_line);
+
#endif
diff --git a/src/dged/buffer_view.c b/src/dged/buffer_view.c
index 15aa812..23bd8e2 100644
--- a/src/dged/buffer_view.c
+++ b/src/dged/buffer_view.c
@@ -3,6 +3,7 @@
#include "buffer.h"
#include "buffer_view.h"
#include "display.h"
+#include "timers.h"
#include "utf8.h"
struct modeline {
@@ -139,6 +140,10 @@ void buffer_view_indent(struct buffer_view *view) {
view->dot = buffer_indent(view->buffer, view->dot);
}
+void buffer_view_indent_alt(struct buffer_view *view) {
+ view->dot = buffer_indent_alt(view->buffer, view->dot);
+}
+
void buffer_view_copy(struct buffer_view *view) {
if (!view->mark_set) {
return;
@@ -214,6 +219,18 @@ void buffer_view_kill_line(struct buffer_view *view) {
buffer_cut(view->buffer, reg);
}
+void buffer_view_sort_lines(struct buffer_view *view) {
+ struct region reg = region_new(view->dot, view->mark);
+ if (view->mark_set && region_has_size(reg)) {
+ if (reg.end.line > 0 && buffer_num_chars(view->buffer, reg.end.line) == 0) {
+ reg.end.line -= 1;
+ }
+
+ buffer_sort_lines(view->buffer, reg.begin.line, reg.end.line);
+ buffer_view_clear_mark(view);
+ }
+}
+
void buffer_view_set_mark(struct buffer_view *view) {
buffer_view_set_mark_at(view, view->dot);
}
@@ -314,23 +331,14 @@ static uint32_t render_line_numbers(struct buffer_view *view,
static void render_modeline(struct modeline *modeline, struct buffer_view *view,
struct command_list *commands, uint32_t window_id,
- uint32_t width, uint32_t height,
- uint64_t frame_time) {
+ uint32_t width, uint32_t height, float frame_time) {
char buf[width * 4];
-
- static uint64_t samples[10] = {0};
- static uint32_t samplei = 0;
- static uint64_t avg = 0;
-
- // calc a moving average with a window of the last 10 frames
- ++samplei;
- samplei %= 10;
- avg += 0.1 * (frame_time - samples[samplei]);
- samples[samplei] = frame_time;
+ memset(buf, 0, width * 4);
time_t now = time(NULL);
struct tm *lt = localtime(&now);
- char left[128], right[128];
+ static char left[128] = {0};
+ static char right[128] = {0};
snprintf(left, 128, " %c%c %d:%-16s (%d, %d) (%s)",
view->buffer->modified ? '*' : '-',
@@ -357,8 +365,11 @@ static void render_modeline(struct modeline *modeline, struct buffer_view *view,
void buffer_view_update(struct buffer_view *view,
struct buffer_view_update_params *params) {
+ struct timer *buffer_update_timer =
+ timer_start("update-windows.buffer-update");
struct buffer_update_params update_params = {};
buffer_update(view->buffer, &update_params);
+ timer_stop(buffer_update_timer);
uint32_t height = params->height;
uint32_t width = params->width;
@@ -369,6 +380,8 @@ void buffer_view_update(struct buffer_view *view,
(int64_t)view->dot.col);
// render modeline
+ struct timer *render_modeline_timer =
+ timer_start("update-windows.modeline-render");
uint32_t modeline_height = 0;
if (view->modeline != NULL) {
modeline_height = 1;
@@ -387,8 +400,11 @@ void buffer_view_update(struct buffer_view *view,
0)
.line;
}
+ timer_stop(render_modeline_timer);
// render line numbers
+ struct timer *render_linenumbers_timer =
+ timer_start("update-windows.linenum-render");
uint32_t linum_width = 0;
if (view->line_numbers) {
linum_width = render_line_numbers(view, params->commands, height);
@@ -402,6 +418,7 @@ void buffer_view_update(struct buffer_view *view,
view->scroll.col =
buffer_clamp(view->buffer, view->dot.line, view->dot.col).col;
}
+ timer_stop(render_linenumbers_timer);
// color region
if (view->mark_set) {
@@ -420,7 +437,9 @@ void buffer_view_update(struct buffer_view *view,
}
}
- // update buffer
+ // render buffer
+ struct timer *render_buffer_timer =
+ timer_start("update-windows.buffer-render");
struct command_list *buf_cmds = command_list_create(
width * height, params->frame_alloc, params->window_x + linum_width,
params->window_y, view->buffer->name);
@@ -434,5 +453,9 @@ void buffer_view_update(struct buffer_view *view,
// draw buffer commands nested inside this command list
command_list_draw_command_list(params->commands, buf_cmds);
+ timer_stop(render_buffer_timer);
+
+ // TODO: move to somewhere where more correct if buffers
+ // are in more than one view (same with buffer hooks).
buffer_clear_text_properties(view->buffer);
}
diff --git a/src/dged/buffer_view.h b/src/dged/buffer_view.h
index 620c261..4e23b5d 100644
--- a/src/dged/buffer_view.h
+++ b/src/dged/buffer_view.h
@@ -68,6 +68,7 @@ void buffer_view_kill_line(struct buffer_view *view);
void buffer_view_newline(struct buffer_view *view);
void buffer_view_indent(struct buffer_view *view);
+void buffer_view_indent_alt(struct buffer_view *view);
void buffer_view_copy(struct buffer_view *view);
void buffer_view_cut(struct buffer_view *view);
@@ -83,11 +84,13 @@ struct location buffer_view_dot_to_visual(struct buffer_view *view);
void buffer_view_undo(struct buffer_view *view);
+void buffer_view_sort_lines(struct buffer_view *view);
+
struct buffer_view_update_params {
struct command_list *commands;
void *(*frame_alloc)(size_t);
uint32_t window_id;
- int64_t frame_time;
+ float frame_time;
uint32_t width;
uint32_t height;
uint32_t window_x;
diff --git a/src/dged/display.c b/src/dged/display.c
index 85a6e0b..ed6fc00 100644
--- a/src/dged/display.c
+++ b/src/dged/display.c
@@ -2,6 +2,7 @@
#include "display.h"
#include "buffer.h"
+#include "timers.h"
#include "utf8.h"
#include <assert.h>
@@ -358,6 +359,10 @@ void display_render(struct display *display,
struct command_list *command_list) {
struct command_list *cl = command_list;
+ static char name[32] = {0};
+ snprintf(name, 31, "display.cl.%s", cl->name);
+ struct timer *render_timer = timer_start(name);
+
uint8_t fmt_stack[256] = {0};
fmt_stack[0] = ESC;
fmt_stack[1] = '[';
@@ -419,6 +424,8 @@ void display_render(struct display *display,
}
cl = cl->next_list;
}
+
+ timer_stop(render_timer);
}
void hide_cursor() {
diff --git a/src/dged/lang.c b/src/dged/lang.c
index c0b7462..d2d7b34 100644
--- a/src/dged/lang.c
+++ b/src/dged/lang.c
@@ -14,7 +14,7 @@ static void _lang_setting_set_default(const char *id, const char *key,
struct setting_value value);
void define_lang(const char *name, const char *id, const char *pattern,
- uint32_t tab_width) {
+ uint32_t tab_width, bool use_tabs) {
_lang_setting_set_default(
id, "name",
@@ -27,6 +27,9 @@ void define_lang(const char *name, const char *id, const char *pattern,
_lang_setting_set_default(id, "tab-width",
(struct setting_value){.type = Setting_Number,
.number_value = tab_width});
+ _lang_setting_set_default(
+ id, "use-tabs",
+ (struct setting_value){.type = Setting_Bool, .bool_value = use_tabs});
}
static struct language g_fundamental = {
@@ -36,14 +39,15 @@ static struct language g_fundamental = {
void languages_init(bool register_default) {
if (register_default) {
- define_lang("Bash", "bash", "^.*\\.bash$", 4);
- define_lang("C", "c", "^.*\\.(c|h)$", 2);
- define_lang("C++", "cxx", "^.*\\.(cpp|cxx|cc|c++|hh|h)$", 2);
- define_lang("Rust", "rs", "^.*\\.rs$", 4);
- define_lang("Nix", "nix", "^.*\\.nix$", 2);
- define_lang("Make", "make", "^.*(Makefile|\\.mk)$", 4);
- define_lang("Python", "python", "^.*\\.py$", 4);
- define_lang("Git Commit Message", "gitcommit", "^.*COMMIT_EDITMSG$", 4);
+ define_lang("Bash", "bash", "^.*\\.bash$", 4, false);
+ define_lang("C", "c", "^.*\\.(c|h)$", 2, false);
+ define_lang("C++", "cxx", "^.*\\.(cpp|cxx|cc|c++|hh|h)$", 2, false);
+ define_lang("Rust", "rs", "^.*\\.rs$", 4, false);
+ define_lang("Nix", "nix", "^.*\\.nix$", 2, false);
+ define_lang("Make", "make", "^.*(Makefile|\\.mk)$", 4, true);
+ define_lang("Python", "python", "^.*\\.py$", 4, false);
+ define_lang("Git Commit Message", "gitcommit", "^.*COMMIT_EDITMSG$", 4,
+ false);
}
}
diff --git a/src/dged/s8.c b/src/dged/s8.c
new file mode 100644
index 0000000..0566fde
--- /dev/null
+++ b/src/dged/s8.c
@@ -0,0 +1,25 @@
+#include "s8.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+bool s8eq(struct s8 s1, struct s8 s2) {
+ return s1.l == s2.l && memcmp(s1.s, s2.s, s1.l) == 0;
+}
+
+int s8cmp(struct s8 s1, struct s8 s2) {
+ if (s1.l < s2.l) {
+ return memcmp(s1.s, s2.s, s1.l);
+ } else if (s2.l < s1.l) {
+ return memcmp(s1.s, s2.s, s2.l);
+ }
+
+ return memcmp(s1.s, s2.s, s1.l);
+}
+
+char *s8tocstr(struct s8 s) {
+ char *cstr = (char *)malloc(s.l + 1);
+ memcpy(cstr, s.s, s.l);
+ cstr[s.l] = '\0';
+ return cstr;
+}
diff --git a/src/dged/s8.h b/src/dged/s8.h
new file mode 100644
index 0000000..955a642
--- /dev/null
+++ b/src/dged/s8.h
@@ -0,0 +1,18 @@
+#ifndef _S8_H
+#define _S8_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define s8(s) ((struct s8){s, strlen(s)})
+
+struct s8 {
+ char *s;
+ uint32_t l;
+};
+
+bool s8eq(struct s8 s1, struct s8 s2);
+int s8cmp(struct s8 s1, struct s8 s2);
+char *s8tocstr(struct s8 s);
+
+#endif
diff --git a/src/dged/syntax.c b/src/dged/syntax.c
index 61f09c2..1544d33 100644
--- a/src/dged/syntax.c
+++ b/src/dged/syntax.c
@@ -17,6 +17,7 @@
#include "hash.h"
#include "minibuffer.h"
#include "path.h"
+#include "s8.h"
#include "settings.h"
#include "text.h"
#include "vec.h"
@@ -26,25 +27,6 @@ static uint32_t treesitter_path_len = 0;
static const char *parser_filename = "parser";
static const char *highlight_path = "queries/highlights.scm";
-// TODO: move to own file
-#define s8(s) ((struct s8){s, strlen(s)})
-
-struct s8 {
- char *s;
- uint32_t l;
-};
-
-static bool s8eq(struct s8 s1, struct s8 s2) {
- return s1.l == s2.l && memcmp(s1.s, s2.s, s1.l) == 0;
-}
-
-static char *s8tocstr(struct s8 s) {
- char *cstr = (char *)malloc(s.l + 1);
- memcpy(cstr, s.s, s.l);
- cstr[s.l] = '\0';
- return cstr;
-}
-
struct predicate {
uint32_t pattern_idx;
diff --git a/src/dged/text.c b/src/dged/text.c
index 3942efc..0a92933 100644
--- a/src/dged/text.c
+++ b/src/dged/text.c
@@ -421,6 +421,7 @@ void text_for_each_line(struct text *text, uint32_t line, uint32_t nlines,
for (uint32_t li = line; li < nlines_max; ++li) {
struct line *src_line = &text->lines[li];
struct text_chunk line = (struct text_chunk){
+ .allocated = false,
.text = src_line->data,
.nbytes = src_line->nbytes,
.nchars = src_line->nchars,
diff --git a/src/dged/timers.c b/src/dged/timers.c
new file mode 100644
index 0000000..37ac367
--- /dev/null
+++ b/src/dged/timers.c
@@ -0,0 +1,95 @@
+#include "timers.h"
+#include "hash.h"
+#include "hashmap.h"
+
+#include <stdbool.h>
+#include <string.h>
+#include <time.h>
+
+#define NUM_FRAME_SAMPLES 16
+
+struct timer {
+ char name[32];
+ uint64_t samples[NUM_FRAME_SAMPLES];
+ struct timespec started_at;
+};
+
+HASHMAP_ENTRY_TYPE(timer_entry, struct timer);
+
+static struct timers {
+ uint32_t frame_index;
+ HASHMAP(struct timer_entry) timers;
+} g_timers;
+
+void timers_init() {
+ HASHMAP_INIT(&g_timers.timers, 32, hash_name);
+ g_timers.frame_index = 0;
+}
+
+void timers_destroy() { HASHMAP_DESTROY(&g_timers.timers); }
+
+void timers_start_frame() {
+ HASHMAP_FOR_EACH(&g_timers.timers, struct timer_entry * entry) {
+ struct timer *timer = &entry->value;
+ timer->samples[g_timers.frame_index] = 0;
+ }
+}
+
+void timers_end_frame() {
+ g_timers.frame_index = (g_timers.frame_index + 1) % NUM_FRAME_SAMPLES;
+}
+
+struct timer *timer_start(const char *name) {
+ HASHMAP_GET(&g_timers.timers, struct timer_entry, name, struct timer * t);
+ if (t == NULL) {
+ HASHMAP_APPEND(&g_timers.timers, struct timer_entry, name,
+ struct timer_entry * tnew);
+ struct timer *new_timer = &tnew->value;
+
+ size_t namelen = strlen(name);
+ namelen = namelen >= 32 ? 31 : namelen;
+ memcpy(new_timer->name, name, namelen);
+ new_timer->name[namelen] = '\0';
+
+ memset(new_timer->samples, 0, sizeof(uint64_t) * NUM_FRAME_SAMPLES);
+
+ t = new_timer;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &t->started_at);
+ return t;
+}
+
+void timer_stop(struct timer *timer) {
+ struct timespec end;
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ uint64_t elapsed = ((uint64_t)end.tv_sec * 1e9 + (uint64_t)end.tv_nsec) -
+ ((uint64_t)timer->started_at.tv_sec * 1e9 +
+ (uint64_t)timer->started_at.tv_nsec);
+
+ timer->samples[g_timers.frame_index] += elapsed;
+}
+
+struct timer *timer_get(const char *name) {
+ HASHMAP_GET(&g_timers.timers, struct timer_entry, name, struct timer * t);
+ return t;
+}
+
+float timer_average(const struct timer *timer) {
+ uint64_t sum = 0;
+ for (uint32_t samplei = 0; samplei < NUM_FRAME_SAMPLES; ++samplei) {
+ sum += timer->samples[samplei];
+ }
+
+ return (float)sum / NUM_FRAME_SAMPLES;
+ return 0.f;
+}
+
+const char *timer_name(const struct timer *timer) { return timer->name; }
+
+void timers_for_each(timer_callback callback, void *userdata) {
+ HASHMAP_FOR_EACH(&g_timers.timers, struct timer_entry * entry) {
+ const struct timer *timer = &entry->value;
+ callback(timer, userdata);
+ }
+}
diff --git a/src/dged/timers.h b/src/dged/timers.h
new file mode 100644
index 0000000..4911b54
--- /dev/null
+++ b/src/dged/timers.h
@@ -0,0 +1,21 @@
+#ifndef _TIMERS_H
+#define _TIMERS_H
+
+struct timer;
+
+void timers_init();
+void timers_start_frame();
+
+struct timer *timer_start(const char *name);
+void timer_stop(struct timer *timer);
+struct timer *timer_get(const char *name);
+float timer_average(const struct timer *timer);
+const char *timer_name(const struct timer *timer);
+
+typedef void (*timer_callback)(const struct timer *timer, void *userdata);
+void timers_for_each(timer_callback callback, void *userdata);
+
+void timers_end_frame();
+void timers_destroy();
+
+#endif
diff --git a/src/dged/window.c b/src/dged/window.c
index da2cebe..8fcd51c 100644
--- a/src/dged/window.c
+++ b/src/dged/window.c
@@ -154,7 +154,7 @@ void windows_resize(uint32_t height, uint32_t width) {
window_tree_resize(BINTREE_ROOT(&g_windows.windows), height - 1, width);
}
-void windows_update(void *(*frame_alloc)(size_t), uint64_t frame_time) {
+void windows_update(void *(*frame_alloc)(size_t), float frame_time) {
struct window *w = &g_minibuffer_window;
w->x = 0;
@@ -281,8 +281,8 @@ void windows_update(void *(*frame_alloc)(size_t), uint64_t frame_time) {
while (n != NULL) {
struct window *w = &BINTREE_VALUE(n);
if (w->type == Window_Buffer) {
- char name[16];
- snprintf(name, 16, "bufview-%s", w->buffer_view.buffer->name);
+ char name[16] = {0};
+ snprintf(name, 15, "bufview-%s", w->buffer_view.buffer->name);
w->commands = command_list_create(w->height * w->width, frame_alloc, w->x,
w->y, name);
diff --git a/src/dged/window.h b/src/dged/window.h
index e9f90aa..3841475 100644
--- a/src/dged/window.h
+++ b/src/dged/window.h
@@ -25,7 +25,7 @@ void windows_init(uint32_t height, uint32_t width,
void windows_destroy();
void windows_resize(uint32_t height, uint32_t width);
-void windows_update(void *(*frame_alloc)(size_t), uint64_t frame_time);
+void windows_update(void *(*frame_alloc)(size_t), float frame_time);
void windows_render(struct display *display);
struct window *root_window();