]> git.lizzy.rs Git - nothing.git/blobdiff - src/ui/console.c
create_lt() -> {0}
[nothing.git] / src / ui / console.c
index 0811334a7b6f71ce4a5e279994243037f6022189..3f8b7c794039252f9c7a3149011e53bc6305a15e 100644 (file)
@@ -1,95 +1,69 @@
-#include <assert.h>
+#include "system/stacktrace.h"
 
+#include "ebisp/gc.h"
+#include "ebisp/interpreter.h"
+#include "ebisp/parser.h"
+#include "ebisp/scope.h"
+#include "ebisp/std.h"
 #include "game/level.h"
-#include "game/level/player/rigid_rect.h"
-#include "script/gc.h"
-#include "script/interpreter.h"
-#include "script/parser.h"
-#include "script/scope.h"
 #include "sdl/renderer.h"
-#include "system/error.h"
+#include "system/log.h"
+#include "system/log_script.h"
 #include "system/lt.h"
+#include "system/nth_alloc.h"
 #include "ui/console.h"
+#include "ui/console_log.h"
 #include "ui/edit_field.h"
 #include "ui/history.h"
-#include "ui/log.h"
+#include "broadcast.h"
 
 #define FONT_WIDTH_SCALE 3.0f
 #define FONT_HEIGHT_SCALE 3.0f
 
-#define LOG_CAPACITY 10
+#define CONSOLE_LOG_CAPACITY 10
 #define HISTORY_CAPACITY 20
 #define PROMPT_HEIGHT (FONT_HEIGHT_SCALE * FONT_CHAR_HEIGHT)
-#define LOG_HEIGHT (FONT_HEIGHT_SCALE * FONT_CHAR_HEIGHT * LOG_CAPACITY)
+#define CONSOLE_LOG_HEIGHT (FONT_HEIGHT_SCALE * FONT_CHAR_HEIGHT * CONSOLE_LOG_CAPACITY)
 
-#define CONSOLE_HEIGHT (LOG_HEIGHT + PROMPT_HEIGHT)
+#define CONSOLE_HEIGHT (CONSOLE_LOG_HEIGHT + PROMPT_HEIGHT)
 
 #define SLIDE_DOWN_TIME 0.4f
 
 #define CONSOLE_ALPHA (0.80f)
-#define CONSOLE_BACKGROUND (color(0.20f, 0.20f, 0.20f, CONSOLE_ALPHA))
-#define CONSOLE_FOREGROUND (color(0.80f, 0.80f, 0.80f, CONSOLE_ALPHA))
-#define CONSOLE_ERROR (color(0.80f, 0.50f, 0.50f, CONSOLE_ALPHA))
+#define CONSOLE_BACKGROUND (rgba(0.20f, 0.20f, 0.20f, CONSOLE_ALPHA))
+#define CONSOLE_FOREGROUND (rgba(0.80f, 0.80f, 0.80f, CONSOLE_ALPHA))
+#define CONSOLE_ERROR (rgba(0.80f, 0.50f, 0.50f, CONSOLE_ALPHA))
 
 #define CONSOLE_EVAL_RESULT_SIZE 256
 
 struct Console
 {
-    Lt *lt;
+    Lt lt;
     Gc *gc;
     struct Scope scope;
     Edit_field *edit_field;
-    Log *log;
-    Level *level;
+    Console_Log *console_log;
     History *history;
     float a;
     char *eval_result;
 };
 
-/* TODO(#354): Console does not allow to travel the history by pressing up and down */
 /* TODO(#355): Console does not support Emacs keybindings */
 /* TODO(#356): Console does not support autocompletion */
 /* TODO(#357): Console does not show the state of the GC of the script */
 /* TODO(#358): Console does not support copy, cut, paste operations */
 
-static struct EvalResult rect_apply_force(void *param, Gc *gc, struct Scope *scope, struct Expr args)
-{
-    assert(gc);
-    assert(scope);
-    assert(param);
-
-    Level *level = (Level*) param;
-    const char *rect_id = CAR(args).atom->str;
-    struct Expr vector_force_expr = CAR(CDR(args));
-    const float force_x = (float) CAR(vector_force_expr).atom->num;
-    const float force_y = (float) CDR(vector_force_expr).atom->num;
-
-    print_expr_as_sexpr(args); printf("\n");
-
-    Rigid_rect *rigid_rect = level_rigid_rect(level, rect_id);
-    if (rigid_rect != NULL) {
-        printf("Found rect `%s`\n", rect_id);
-        printf("Applying force (%f, %f)\n", force_x, force_y);
-        rigid_rect_apply_force(rigid_rect, vec(force_x, force_y));
-    } else {
-        fprintf(stderr, "Couldn't find rigid_rect `%s`", rect_id);
-    }
-
-    return eval_success(NIL(gc));
-}
-
-Console *create_console(Level *level,
+Console *create_console(Broadcast *broadcast,
                         const Sprite_font *font)
 {
-    Lt *lt = create_lt();
+    Lt lt = {0};
 
     if (lt == NULL) {
         return NULL;
     }
 
-    Console *console = PUSH_LT(lt, malloc(sizeof(Console)), free);
+    Console *console = PUSH_LT(lt, nth_calloc(1, sizeof(Console)), free);
     if (console == NULL) {
-        throw_error(ERROR_TYPE_LIBC);
         RETURN_LT(lt, NULL);
     }
     console->lt = lt;
@@ -102,11 +76,11 @@ Console *create_console(Level *level,
     console->scope.expr = CONS(console->gc,
                                NIL(console->gc),
                                NIL(console->gc));
-    set_scope_value(
-        console->gc,
-        &console->scope,
-        SYMBOL(console->gc, "rect-apply-force"),
-        NATIVE(console->gc, rect_apply_force, level));
+
+    load_std_library(console->gc, &console->scope);
+    load_log_library(console->gc, &console->scope);
+    /* TODO(#669): how to report EvalResult error from create_console? */
+    broadcast_load_library(broadcast, console->gc, &console->scope);
 
     console->edit_field = PUSH_LT(
         lt,
@@ -119,20 +93,19 @@ Console *create_console(Level *level,
         RETURN_LT(lt, NULL);
     }
 
-    console->log = PUSH_LT(
+    console->console_log = PUSH_LT(
         lt,
-        create_log(
+        create_console_log(
             font,
             vec(FONT_WIDTH_SCALE, FONT_HEIGHT_SCALE),
-            LOG_CAPACITY),
-        destroy_log);
+            CONSOLE_LOG_CAPACITY),
+        destroy_console_log);
 
-    console->level = level;
     console->a = 0;
 
     console->eval_result = PUSH_LT(
         lt,
-        malloc(sizeof(char) * CONSOLE_EVAL_RESULT_SIZE),
+        nth_calloc(1, sizeof(char) * CONSOLE_EVAL_RESULT_SIZE),
         free);
     if (console->eval_result == NULL) {
         RETURN_LT(lt, NULL);
@@ -152,78 +125,88 @@ Console *create_console(Level *level,
 
 void destroy_console(Console *console)
 {
-    assert(console);
+    trace_assert(console);
     RETURN_LT0(console->lt);
 }
 
-int console_handle_event(Console *console,
-                         const SDL_Event *event)
+static int console_eval_input(Console *console)
 {
-    switch(event->type) {
-    case SDL_KEYDOWN:
-        switch(event->key.keysym.sym) {
-        case SDLK_RETURN: {
-            const char *source_code = edit_field_as_text(console->edit_field);
+    const char *source_code = edit_field_as_text(console->edit_field);
 
-            /* TODO(#387): console pushes empty strings to the history */
-            if (history_push(console->history, source_code) < 0) {
-                return -1;
-            }
+    /* TODO(#387): console pushes empty strings to the history */
+    if (history_push(console->history, source_code) < 0) {
+        return -1;
+    }
 
-            if (log_push_line(console->log, source_code, CONSOLE_FOREGROUND) < 0) {
+    if (console_log_push_line(console->console_log, source_code, CONSOLE_FOREGROUND) < 0) {
+        return -1;
+    }
+
+    while (*source_code != 0) {
+        struct ParseResult parse_result = read_expr_from_string(console->gc,
+                                                                source_code);
+
+        if (parse_result.is_error) {
+            if (console_log_push_line(console->console_log, parse_result.error_message, CONSOLE_ERROR)) {
                 return -1;
             }
 
-            struct ParseResult parse_result = read_expr_from_string(console->gc,
-                                                                    source_code);
+            edit_field_clean(console->edit_field);
+
+            return 0;
+        }
 
-            if (parse_result.is_error) {
-                if (log_push_line(console->log, parse_result.error_message, CONSOLE_ERROR)) {
-                    return -1;
-                }
+        struct EvalResult eval_result = eval(
+            console->gc,
+            &console->scope,
+            parse_result.expr);
 
-                edit_field_clean(console->edit_field);
+        if (expr_as_sexpr(
+                eval_result.expr,
+                console->eval_result,
+                CONSOLE_EVAL_RESULT_SIZE) < 0) {
+            return -1;
+        }
 
-                return 0;
-            }
+        if (console_log_push_line(console->console_log,
+                          console->eval_result,
+                          eval_result.is_error ?
+                          CONSOLE_ERROR :
+                          CONSOLE_FOREGROUND)) {
+            return -1;
+        }
 
-            struct EvalResult eval_result = eval(
-                console->gc,
-                &console->scope,
-                parse_result.expr);
+        source_code = next_token(parse_result.end).begin;
+    }
 
-            if (expr_as_sexpr(
-                    eval_result.expr,
-                    console->eval_result,
-                    CONSOLE_EVAL_RESULT_SIZE) < 0) {
-                return -1;
-            }
+    gc_collect(console->gc, console->scope.expr);
+    edit_field_clean(console->edit_field);
 
-            if (log_push_line(console->log,
-                              console->eval_result,
-                              eval_result.is_error ?
-                              CONSOLE_ERROR :
-                              CONSOLE_FOREGROUND)) {
-                return -1;
-            }
+    return 0;
+}
 
-            gc_collect(console->gc, console->scope.expr);
-            edit_field_clean(console->edit_field);
-        } return 0;
+int console_handle_event(Console *console,
+                         const SDL_Event *event)
+{
+    switch(event->type) {
+    case SDL_KEYDOWN:
+        switch(event->key.keysym.sym) {
+        case SDLK_RETURN:
+            return console_eval_input(console);
 
-        case SDLK_UP: {
+        case SDLK_UP:
             edit_field_replace(
                 console->edit_field,
                 history_current(console->history));
             history_prev(console->history);
-        } return 0;
+            return 0;
 
-        case SDLK_DOWN: {
+        case SDLK_DOWN:
             edit_field_replace(
                 console->edit_field,
                 history_current(console->history));
             history_next(console->history);
-        } return 0;
+            return 0;
         }
         break;
     }
@@ -249,7 +232,7 @@ int console_render(const Console *console,
         return -1;
     }
 
-    if (log_render(console->log,
+    if (console_log_render(console->console_log,
                    renderer,
                    vec(0.0f, y)) < 0) {
         return -1;
@@ -257,7 +240,7 @@ int console_render(const Console *console,
 
     if (edit_field_render(console->edit_field,
                           renderer,
-                          vec(0.0f, y + LOG_HEIGHT)) < 0) {
+                          vec(0.0f, y + CONSOLE_LOG_HEIGHT)) < 0) {
         return -1;
     }
 
@@ -266,9 +249,7 @@ int console_render(const Console *console,
 
 int console_update(Console *console, float delta_time)
 {
-    assert(console);
-
-    /* TODO(#366): console slide down animation doesn't have any easing */
+    trace_assert(console);
 
     if (console->a < 1.0f) {
         console->a += 1.0f / SLIDE_DOWN_TIME * delta_time;
@@ -283,6 +264,6 @@ int console_update(Console *console, float delta_time)
 
 void console_slide_down(Console *console)
 {
-    assert(console);
+    trace_assert(console);
     console->a = 0.0f;
 }