]> git.lizzy.rs Git - nothing.git/blob - src/broadcast.c
(#882) Make the Platform level loadable
[nothing.git] / src / broadcast.c
1 #include <stdlib.h>
2 #include <string.h>
3
4 #include "system/stacktrace.h"
5 #include "system/nth_alloc.h"
6 #include "broadcast.h"
7 #include "ebisp/interpreter.h"
8 #include "ebisp/expr.h"
9 #include "ebisp/scope.h"
10 #include "game.h"
11
12 struct EvalResult
13 unknown_target(Gc *gc, const char *source, const char *target)
14 {
15     return eval_failure(
16         list(gc, "qqq", "unknown-target", source, target));
17 }
18
19 static struct EvalResult
20 send(void *param, Gc *gc, struct Scope *scope, struct Expr args)
21 {
22     trace_assert(param);
23     trace_assert(gc);
24     trace_assert(scope);
25
26     Broadcast *broadcast = (Broadcast*) param;
27
28     struct Expr path = void_expr();
29     struct EvalResult result = match_list(gc, "e", args, &path);
30     if (result.is_error) {
31         return result;
32     }
33
34     return broadcast_send(broadcast, gc, scope, path);
35 }
36
37 struct Broadcast
38 {
39     Game *game;
40 };
41
42 Broadcast *create_broadcast(Game *game)
43 {
44     trace_assert(game);
45
46     Broadcast *broadcast = nth_calloc(1, sizeof(Broadcast));
47     if (broadcast == NULL) {
48         return NULL;
49     }
50
51     broadcast->game = game;
52
53     return broadcast;
54 }
55
56 void destroy_broadcast(Broadcast *broadcast)
57 {
58     trace_assert(broadcast);
59     free(broadcast);
60 }
61
62 struct EvalResult
63 broadcast_send(Broadcast *broadcast,
64                Gc *gc,
65                struct Scope *scope,
66                struct Expr path)
67 {
68     trace_assert(broadcast);
69     trace_assert(gc);
70     trace_assert(scope);
71
72     const char *target = NULL;
73     struct Expr rest = void_expr();
74     struct EvalResult res = match_list(gc, "q*", path, &target, &rest);
75     if (res.is_error) {
76         return res;
77     }
78
79     if (strcmp(target, "game") == 0) {
80         return game_send(broadcast->game, gc, scope, rest);
81     }
82
83     return unknown_target(gc, "game", target);
84 }
85
86 void broadcast_load_library(Broadcast *broadcast,
87                             Gc *gc,
88                             struct Scope *scope)
89 {
90     trace_assert(gc);
91     trace_assert(scope);
92     trace_assert(broadcast);
93
94     set_scope_value(gc, scope, SYMBOL(gc, "send"), NATIVE(gc, send, broadcast));
95 }