]> git.lizzy.rs Git - nothing.git/blob - src/broadcast.c
(#726) Add cmake module for libxml2
[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 #include "broadcast_lisp.h"
12
13 struct EvalResult
14 unknown_target(Gc *gc, const char *source, const char *target)
15 {
16     return eval_failure(
17         list(gc, "qqq", "unknown-target", source, target));
18 }
19
20 static struct EvalResult
21 send(void *param, Gc *gc, struct Scope *scope, struct Expr args)
22 {
23     trace_assert(param);
24     trace_assert(gc);
25     trace_assert(scope);
26
27     Broadcast *broadcast = (Broadcast*) param;
28
29     struct Expr path = void_expr();
30     struct EvalResult result = match_list(gc, "e", args, &path);
31     if (result.is_error) {
32         return result;
33     }
34
35     return broadcast_send(broadcast, gc, scope, path);
36 }
37
38 struct Broadcast
39 {
40     Game *game;
41 };
42
43 Broadcast *create_broadcast(Game *game)
44 {
45     trace_assert(game);
46
47     Broadcast *broadcast = nth_alloc(sizeof(Broadcast));
48     if (broadcast == NULL) {
49         return NULL;
50     }
51
52     broadcast->game = game;
53
54     return broadcast;
55 }
56
57 void destroy_broadcast(Broadcast *broadcast)
58 {
59     trace_assert(broadcast);
60     free(broadcast);
61 }
62
63 struct EvalResult
64 broadcast_send(Broadcast *broadcast,
65                Gc *gc,
66                struct Scope *scope,
67                struct Expr path)
68 {
69     trace_assert(broadcast);
70     trace_assert(gc);
71     trace_assert(scope);
72
73     const char *target = NULL;
74     struct Expr rest = void_expr();
75     struct EvalResult res = match_list(gc, "q*", path, &target, &rest);
76     if (res.is_error) {
77         return res;
78     }
79
80     if (strcmp(target, "game") == 0) {
81         return game_send(broadcast->game, gc, scope, rest);
82     }
83
84     return unknown_target(gc, "game", target);
85 }
86
87 struct EvalResult broadcast_load_library(Broadcast *broadcast,
88                                          Gc *gc,
89                                          struct Scope *scope)
90 {
91     trace_assert(gc);
92     trace_assert(scope);
93     trace_assert(broadcast);
94
95     set_scope_value(gc, scope, SYMBOL(gc, "send-native"), NATIVE(gc, send, broadcast));
96
97     struct EvalResult result = eval_block(gc, scope, broadcast_lisp_library(gc));
98     if (result.is_error) {
99         return result;
100     }
101
102     return eval_success(NIL(gc));
103 }