commit f14601d31e05d8df37e5e5c1e0740967f33b941e
parent 5ac87cda57ab359f8bc268812541261f14e80db0
Author: William Casarin <jb55@jb55.com>
Date: Sat, 3 Jul 2021 08:38:22 -0700
generalize message packets, add entity resources
Diffstat:
24 files changed, 502 insertions(+), 51 deletions(-)
diff --git a/.envrc b/.envrc
@@ -1 +1,3 @@
use nix
+
+export TODO_DIR=$PWD/todo
diff --git a/.gitignore b/.gitignore
@@ -1,8 +1,11 @@
*.o
+.buildcmd
.build-result
/protoverse
/libprotoverse.a
/TAGS
+todo/report.txt
+todo/done.txt
/test
*.wasm
/tags
diff --git a/Makefile b/Makefile
@@ -1,5 +1,7 @@
-CFLAGS = -Wno-error=unused-function -Ofast -std=gnu90 -Wall -Wextra -Werror -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement
+CFLAGS = -Wno-error=unused-function -Ofast -std=gnu90 -Wall -Wextra -Werror \
+ -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes \
+ -Wmissing-declarations -Wdeclaration-after-statement
OBJS = src/io.o \
src/parse.o \
@@ -9,6 +11,7 @@ OBJS = src/io.o \
src/net.o \
src/varint.o \
src/parser.o \
+ src/resource.o \
src/wasm.o
WASMS = wasm/hello-c.wasm \
diff --git a/default.nix b/default.nix
@@ -1,6 +1,4 @@
{ pkgs ? import <nixpkgs> {} }:
-with pkgs;
-stdenv.mkDerivation {
- name = "protoverse";
- nativeBuildInputs = [ gdb wabt emscripten ];
+pkgs.mkShell {
+ buildInputs = with pkgs; [ gdb wabt emscripten wasmtime ];
}
diff --git a/index.space b/index.space
@@ -0,0 +1 @@
+satoshis-citadel.space+
\ No newline at end of file
diff --git a/satoshis-citadel.space b/satoshis-citadel.space
@@ -17,6 +17,8 @@
(chair (id welcome-desk-chair)
(name "fancy"))
+ (chair (name "throne") (material "invisible"))
+
(light (location ceiling)
(name "ceiling")
(state off)
diff --git a/src/client.c b/src/client.c
@@ -65,9 +65,8 @@ int protoverse_connect(const char *server_ip_str, int port)
server_addr.sin_port = port == 0 || port == -1 ? 1988 : port;
server_addr.sin_addr = server_in_addr;
- packet.type = PKT_CHAT;
- packet.data.chat.message = "hello, world";
- packet.data.chat.sender = 0xFFFFFF;
+ packet.type = PKT_MESSAGE;
+ packet.data.message.message = "hello, world";
send_packet(sockfd, &server_addr, &packet);
recv_packet(sockfd, &cursor, &server_addr, &packet);
diff --git a/src/debug.h b/src/debug.h
@@ -0,0 +1,15 @@
+
+#ifndef PROTOVERSE_DEBUG_H
+#define PROTOVERSE_DEBUG_H
+
+#include <stdio.h>
+
+#define unusual(...) fprintf(stderr, "UNUSUAL: " __VA_ARGS__)
+
+#ifdef DEBUG
+#define debug(...) fprintf(stderr, __VA_ARGS__)
+#else
+#define debug(...)
+#endif
+
+#endif /* PROTOVERSE_DEBUG_H */
diff --git a/src/entity.h b/src/entity.h
@@ -0,0 +1,21 @@
+
+#ifndef PROTOVERSE_ENTITY_H
+#define PROTOVERSE_ENTITY_H
+
+#include "resource.h"
+
+typedef struct resource_id entity_id;
+
+enum entity_type {
+ ENT_AVATAR,
+ ENT_OBJECT,
+};
+
+struct entity {
+ const char *name;
+ enum entity_type type;
+ int cell;
+ double pos[3];
+};
+
+#endif /* PROTOVERSE_ENTITY_H */
diff --git a/src/env.h b/src/env.h
@@ -0,0 +1,10 @@
+#ifndef PROTOVERSE_ENV
+#define PROTOVERSE_ENV
+
+#include "resource.h"
+
+struct env {
+ struct resource_manager entities;
+};
+
+#endif /* PROTOVERSE_ENV */
diff --git a/src/net.c b/src/net.c
@@ -3,6 +3,8 @@
#include "cursor.h"
#include "util.h"
#include "varint.h"
+#include "env.h"
+#include "entity.h"
#include <sys/types.h>
#include <assert.h>
@@ -13,7 +15,8 @@
#include <stdio.h>
#include <string.h>
-static int push_fetch_response_packet(struct cursor *c, struct fetch_response_packet *resp)
+static int push_fetch_response_packet(struct cursor *c,
+ struct fetch_response_packet *resp)
{
int ok;
ok = push_prefixed_str(c, resp->path);
@@ -40,23 +43,29 @@ static int push_fetch_packet(struct cursor *c, struct fetch_packet *fetch)
}
/* TODO: CPU-independent encoding */
-static int push_chat_packet(struct cursor *c, struct chat_packet *chat)
+static int push_message_packet(struct cursor *c, struct message_packet *msg)
{
int ok;
- ok = push_varint(c, chat->sender);
+ ok = push_varint(c, msg->type);
if (!ok) return 0;
- return push_prefixed_str(c, chat->message);
+ ok = push_varint(c, msg->receiver);
+ if (!ok) return 0;
+
+ return push_prefixed_str(c, msg->message);
}
-static int pull_chat_packet(struct cursor *c, struct cursor *buf, struct chat_packet *chat)
+static int pull_message_packet(struct cursor *c, struct cursor *buf, struct message_packet *msg)
{
int ok;
- ok = pull_varint(c, &chat->sender);
+ ok = pull_varint(c, &msg->type);
+ if (!ok) return 0;
+
+ ok = pull_varint(c, &msg->receiver);
if (!ok) return 0;
- return pull_prefixed_str(c, buf, &chat->message);
+ return pull_prefixed_str(c, buf, &msg->message);
}
static int pull_fetch_packet(struct cursor *c, struct cursor *buf, struct fetch_packet *fetch)
@@ -73,10 +82,12 @@ int send_packet(int sockfd, struct sockaddr_in *to_addr, struct packet *packet)
len = push_packet(buf, sizeof(buf), packet);
if (!len) return 0;
- ok = sendto(sockfd, buf, len, 0, (struct sockaddr*)to_addr, sizeof(*to_addr));
+ ok = sendto(sockfd, buf, len, 0, (struct sockaddr*)to_addr,
+ sizeof(*to_addr));
if (ok != len) {
- printf("sendto: sent %d != packet_len %d - %s\n", ok, len, strerror(errno));
+ printf("sendto: sent %d != packet_len %d - %s\n", ok, len,
+ strerror(errno));
return 0;
}
@@ -90,7 +101,8 @@ int recv_packet(int sockfd, struct cursor *buf, struct sockaddr_in *from, struct
socklen_t size = sizeof(*from);
int bytes;
- bytes = recvfrom(sockfd, tmp, sizeof(tmp), 0, (struct sockaddr*)from, &size);
+ bytes = recvfrom(sockfd, tmp, sizeof(tmp), 0, (struct sockaddr*)from,
+ &size);
assert(size == sizeof(*from));
make_cursor(tmp, tmp + sizeof(tmp), &tmp_cursor);
@@ -114,7 +126,8 @@ static int push_envelope(struct cursor *cursor, enum packet_type type, int len)
return env_len;
}
-static int pull_envelope(struct cursor *cursor, enum packet_type *type, int *len)
+static int pull_envelope(struct cursor *cursor, enum packet_type *type,
+ int *len)
{
int ok, env_len;
ok = pull_varint(cursor, (int*)type);
@@ -139,9 +152,10 @@ static int push_packet_data(struct cursor *c, struct packet *packet)
case PKT_FETCH_DATA:
return push_fetch_packet(c, &packet->data.fetch);
case PKT_FETCH_DATA_RESPONSE:
- return push_fetch_response_packet(c, &packet->data.fetch_response);
- case PKT_CHAT:
- return push_chat_packet(c, &packet->data.chat);
+ return push_fetch_response_packet(c,
+ &packet->data.fetch_response);
+ case PKT_MESSAGE:
+ return push_message_packet(c, &packet->data.message);
case PKT_NUM_TYPES:
return 0;
}
@@ -184,8 +198,8 @@ static int pull_packet_data(struct cursor *c, struct cursor *buf,
case PKT_FETCH_DATA_RESPONSE:
return pull_fetch_response_packet(c, buf,
&packet->data.fetch_response);
- case PKT_CHAT:
- return pull_chat_packet(c, buf, &packet->data.chat);
+ case PKT_MESSAGE:
+ return pull_message_packet(c, buf, &packet->data.message);
case PKT_NUM_TYPES:
break;
}
@@ -209,7 +223,8 @@ int pull_packet(struct cursor *c, struct cursor *buf, struct packet *packet,
capacity_left = cursor_remaining_capacity(c) - 1;
if (len > capacity_left) {
- printf("sanity: packet larger (%d) than remaining buffer size: %d", len, capacity_left);
+ printf("sanity: packet larger (%d)"
+ " than remaining buffer size: %d", len, capacity_left);
return 0;
}
@@ -219,13 +234,13 @@ int pull_packet(struct cursor *c, struct cursor *buf, struct packet *packet,
return len + env_size;
}
-static int packet_chat_eq(struct chat_packet *a, struct chat_packet *b)
+static int packet_message_eq(struct message_packet *a, struct message_packet *b)
{
/* fail if either is 0 but not both 0 or both not 0 */
if (!a->message ^ !b->message)
return 0;
- return a->sender == b->sender && !strcmp(a->message, b->message);
+ return !strcmp(a->message, b->message);
}
static int packet_fetch_eq(struct fetch_packet *a, struct fetch_packet *b)
@@ -251,8 +266,8 @@ int packet_eq(struct packet *a, struct packet *b)
return 0;
switch (a->type) {
- case PKT_CHAT:
- return packet_chat_eq(&a->data.chat, &b->data.chat);
+ case PKT_MESSAGE:
+ return packet_message_eq(&a->data.message, &b->data.message);
case PKT_FETCH_DATA:
return packet_fetch_eq(&a->data.fetch, &b->data.fetch);
case PKT_FETCH_DATA_RESPONSE:
@@ -265,14 +280,30 @@ int packet_eq(struct packet *a, struct packet *b)
return 0;
}
+static const char *entity_name(struct env *env, entity_id *id)
+{
+ struct entity *ent;
+
+ if (!(ent = get_resource(&env->entities, id))) {
+ return "unknown";
+ }
+
+ return ent->name;
+}
+
+static void print_message_packet(struct env *env, struct message_packet *msg)
+{
+ /* eventually print entity data from environment */
+ (void)env;
+ printf("(message (to %d) (msg '%s'))\n", msg->receiver,
+ msg->message);
+}
-void print_packet(struct packet *packet)
+void print_packet(struct env *env, struct packet *packet)
{
switch (packet->type) {
- case PKT_CHAT:
- printf("(chat (sender %d) (message \"%s\"))\n",
- packet->data.chat.sender,
- packet->data.chat.message);
+ case PKT_MESSAGE:
+ print_message_packet(env, &packet->data.message);
return;
case PKT_FETCH_DATA_RESPONSE:
printf("(fetch-resp (path \"%s\") (data %d))\n",
diff --git a/src/net.h b/src/net.h
@@ -4,15 +4,22 @@
#include <sys/socket.h>
#include <arpa/inet.h>
+
#include "cursor.h"
+#include "env.h"
enum packet_type {
PKT_FETCH_DATA,
PKT_FETCH_DATA_RESPONSE,
- PKT_CHAT,
+ PKT_MESSAGE,
PKT_NUM_TYPES,
};
+enum message_type {
+ MSG_CHAT,
+ MSG_INTERACT,
+};
+
struct fetch_packet {
const char *path;
};
@@ -23,15 +30,16 @@ struct fetch_response_packet {
unsigned char *data;
};
-struct chat_packet {
- int sender;
+struct message_packet {
+ int receiver;
+ int type;
const char *message;
};
union packet_data {
struct fetch_packet fetch;
struct fetch_response_packet fetch_response;
- struct chat_packet chat;
+ struct message_packet message;
};
struct packet {
@@ -46,6 +54,6 @@ int push_packet(unsigned char *buf, int bufsize, struct packet *packet);
int pull_packet(struct cursor *c, struct cursor *buf, struct packet *packet, int received_bytes);
int packet_eq(struct packet *a, struct packet *b);
-void print_packet(struct packet *packet);
+void print_packet(struct env *env, struct packet *packet);
#endif /* PROTOVERSE_NET_H */
diff --git a/src/object.h b/src/object.h
@@ -0,0 +1,10 @@
+
+#ifndef _PROTOVERSE_OBJECT_
+#define _PROTOVERSE_OBJECT_
+
+struct object {
+ int cell_id;
+ const char *name;
+}
+
+#endif /* _PROTOVERSE_OBJECT_ */
diff --git a/src/parse.c b/src/parse.c
@@ -163,7 +163,6 @@ void print_cell(struct cursor *attributes, struct cell *cell)
: cell_type_str(cell->type));
/* print_attributes(attributes, cell); */
- printf("\n");
}
diff --git a/src/protoverse.c b/src/protoverse.c
@@ -25,12 +25,14 @@ static void print_all_cells(struct parser *parser)
for (i = 0; i < ncells; i++) {
cell = get_cell(parser->cells, i);
print_cell(parser->attributes, cell);
+ printf("\n");
for (j = 0; j < cell->n_children; j++) {
cell = get_cell(parser->cells, cell->children[j]);
assert(cell);
printf(" ");
print_cell(parser->attributes, cell);
+ printf("\n");
}
}
}
@@ -56,6 +58,7 @@ static int print_cell_tree(struct parser *parser, u16 root, int depth)
}
print_cell(&parser->attributes, cell);
+ printf("\n");
for (i = 0; i < cell->n_children; i++) {
print_cell_tree(parser, cell->children[i], depth+1);
diff --git a/src/resource.c b/src/resource.c
@@ -0,0 +1,236 @@
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "resource.h"
+#include "debug.h"
+#include "util.h"
+
+static u64 resource_uuids = 0;
+
+static inline void *index_resource_(u8 *res, u32 elem_size, int i)
+{
+ assert(res);
+ return res + (i * elem_size);
+}
+
+static inline void *index_resource(struct resource_manager *r, int i)
+{
+ return index_resource_(r->resources, r->elem_size, i);
+}
+
+
+void *get_all_resources(struct resource_manager *r, u32 *count, struct resource_id **ids) {
+ if (count != 0)
+ *count = r->resource_count;
+
+ if (ids != 0)
+ *ids = r->ids;
+
+ return r->resources;
+}
+
+void init_id(struct resource_id *id) {
+ id->index = -1;
+ id->generation = -1;
+ id->uuid = -1;
+}
+
+void null_id(struct resource_id *id)
+{
+ id->generation = 0;
+ id->uuid = -1;
+ id->index = -1;
+}
+
+void init_resource_manager(struct resource_manager *r, u32 elem_size,
+ u32 initial_elements, u32 max_elements,
+ const char *name)
+{
+ r->generation = 1;
+ r->resource_count = 0;
+ r->elem_size = elem_size;
+ r->max_capacity = max_elements;
+ r->current_capacity = initial_elements;
+ r->name = name;
+
+ assert(initial_elements != 0);
+
+ r->resources = calloc(r->current_capacity, elem_size);
+ r->ids = calloc(r->current_capacity, sizeof(struct resource_id));
+}
+
+void destroy_resource_manager(struct resource_manager *r) {
+ free(r->ids);
+ free(r->resources);
+}
+
+static int refresh_id(struct resource_manager *r, struct resource_id *id,
+ struct resource_id *new)
+{
+ u32 i;
+ // rollover is ok
+ /* assert(->generation <= esys.generation); */
+ if (id->generation != r->generation) {
+ /* debug("id %llu gen %d != res gen %d, refreshing\n", */
+ /* id->uuid, id->generation, r->generation); */
+ /* try to find uuid in new memory layout */
+ for (i = 0; i < r->resource_count; i++) {
+ struct resource_id *newer_id = &r->ids[i];
+ if (newer_id->uuid == id->uuid) {
+ /* debug("found %llu, ind %d -> %d\n", new_id->uuid, new_id->index, new->index); */
+ new->index = newer_id->index;
+ new->generation = r->generation;
+ return REFRESHED_ID;
+ }
+ }
+
+ // entity was deleted
+ return RESOURCE_DELETED;
+ }
+
+ // doesn't need refreshed
+ return REFRESH_NOT_NEEDED;
+}
+
+int is_resource_destroyed(struct resource_id *id) {
+ return id->generation == 0;
+}
+
+static void new_id(struct resource_manager *r, struct resource_id *id)
+{
+ id->index = r->resource_count;
+ id->uuid = ++resource_uuids;
+ id->generation = r->generation;
+ assert(id->generation);
+}
+
+static void resize(struct resource_manager *r)
+{
+ void *new_mem;
+ u32 new_size;
+
+ debug("resizing %s resources, count %d+1 > current capacity %d\n",
+ r->name, r->resource_count, r->current_capacity);
+
+ new_size = r->resource_count * 1.5;
+ if (new_size >= r->max_capacity) {
+ new_size = r->max_capacity;
+ }
+
+ /* debug("resizing new_size %d\n", new_size); */
+
+ new_mem = realloc(r->resources, (new_size+1) * r->elem_size);
+ if (!new_mem) {
+ // yikes, out of memory, bail
+ assert(new_mem);
+ return;
+ }
+
+ r->resources = new_mem;
+ new_mem = realloc(r->ids, sizeof(struct resource_id) * (new_size+1));
+
+ if (!new_mem) {
+ // yikes, out of memory, bail
+ assert(new_mem);
+ return;
+ }
+ r->current_capacity = new_size;
+ r->ids = new_mem;
+}
+
+void print_id(struct resource_id *id, int nl)
+{
+ printf("id(u:%llu i:%d g:%d)%s",
+ id->uuid, id->index, id->generation, nl?"\n":"");
+}
+
+
+void *new_resource(struct resource_manager *r, struct resource_id *id)
+{
+ struct resource_id *fresh_id;
+
+ assert(id);
+ assert(id->index == 0xFFFFFFFF && "res_id is uninitialized");
+
+ if (r->resource_count + 1 > r->max_capacity) {
+ printf("new_resource: count %d > max cap %d\n", r->resource_count, r->max_capacity);
+ return NULL;
+ }
+
+ if (r->resource_count + 1 > r->current_capacity)
+ resize(r);
+
+ fresh_id = &r->ids[r->resource_count];
+ new_id(r, fresh_id);
+ *id = *fresh_id;
+
+ return index_resource(r, r->resource_count++);
+}
+
+
+void *get_resource(struct resource_manager *r, struct resource_id *id) {
+ enum refresh_status res;
+
+ assert((int64_t)id->generation != -1 && "id intialized but not allocated (needs new_ call)");
+
+ if (id->generation == 0) {
+ /* unusual("getting already deleted resource %llu\n", id->uuid); */
+ return NULL;
+ }
+
+ res = refresh_id(r, id, id);
+
+ if (res == RESOURCE_DELETED) {
+ /* unusual("getting deleted %s resource %llu\n", r->name, id->uuid); */
+ return NULL;
+ }
+
+ return index_resource(r, id->index);
+}
+
+
+void destroy_resource(struct resource_manager *r, struct resource_id *id) {
+ enum refresh_status res;
+ u32 i;
+
+ if (is_resource_destroyed(id)) {
+ unusual("trying to destroy resource %llu which was already destroyed\n", id->uuid);
+ return;
+ }
+
+ res = refresh_id(r, id, id);
+
+ // entity already deleted
+ /* debug("refresh res %d uuid %llu gen %d index %d\n", res, */
+ /* id->uuid, id->generation, id->index); */
+
+ if (res == RESOURCE_DELETED) {
+ unusual("trying to destroy resource %llu which was already destroyed (2)\n", id->uuid);
+ id->generation = 0;
+ return;
+ }
+
+ /* debug("destroying %s resource %llu ind %d res_count %d\n", */
+ /* r->name, id->uuid, id->index, r->resource_count); */
+
+ r->resource_count--;
+ r->generation++;
+
+ assert((int)r->resource_count - (int)id->index >= 0);
+
+ // TODO: we're copying OOB here
+ memmove(index_resource(r, id->index),
+ index_resource(r, id->index+1),
+ r->elem_size * (r->resource_count - id->index));
+
+ memmove(&r->ids[id->index],
+ &r->ids[id->index+1],
+ sizeof(struct resource_id) * (r->resource_count - id->index));
+
+
+ for (i = id->index; i < r->resource_count; i++) {
+ r->ids[i].index--;
+ }
+}
diff --git a/src/resource.h b/src/resource.h
@@ -0,0 +1,56 @@
+
+#ifndef RESOURCE_H
+#define RESOURCE_H
+
+#include "types.h"
+
+#define STATIC_UUID 0x5A51C00000000000
+
+enum refresh_status {
+ RESOURCE_DELETED,
+ REFRESH_NOT_NEEDED,
+ REFRESHED_ID
+};
+
+struct resource_id {
+ u64 uuid;
+ u32 index;
+ u32 generation;
+};
+
+struct resource_manager {
+ u8 *resources;
+ struct resource_id *ids;
+ u32 resource_count;
+ u32 generation;
+ u32 elem_size;
+ u32 slots_used;
+ u32 max_capacity;
+ u32 current_capacity;
+
+ const char *name;
+};
+
+#define ideq(a, b) ((a)->uuid == (b)->uuid)
+
+void init_id(struct resource_id *id);
+void *get_resource(struct resource_manager *r, struct resource_id *id);
+void *get_all_resources(struct resource_manager *, u32 *count, struct resource_id **ids);
+void destroy_resource(struct resource_manager *, struct resource_id *id);
+void destroy_resource_manager(struct resource_manager *);
+void *new_resource(struct resource_manager *, struct resource_id *id);
+void print_id(struct resource_id *, int nl);
+void null_id(struct resource_id *id);
+int is_resource_destroyed(struct resource_id *id);
+
+void init_resource_manager(struct resource_manager *r, u32 elem_size,
+ u32 initial_elements, u32 max_elements, const char *name);
+
+
+static inline int is_null_id(struct resource_id *id)
+{
+ return id->generation == 0;
+}
+
+
+#endif /* RESOURCE_H */
diff --git a/src/serve.c b/src/serve.c
@@ -10,10 +10,12 @@
#include <stdlib.h>
#include "serve.h"
+#include "entity.h"
#include "net.h"
#include "io.h"
#define MAX_CACHED_FILES 12
+#define MAX_ENTITIES 1048576
int inet_aton(const char *cp, struct in_addr *inp);
@@ -62,6 +64,7 @@ static int make_fetch_response(struct cursor *buf,
}
static int handle_packet(int sockfd,
+ struct env *env,
struct cursor *buf,
struct sockaddr_in *from,
struct packet *packet)
@@ -69,9 +72,9 @@ static int handle_packet(int sockfd,
struct packet response;
int ok;
- print_packet(packet);
+ print_packet(env, packet);
switch (packet->type) {
- case PKT_CHAT:
+ case PKT_MESSAGE:
return send_packet(sockfd, from, packet);
case PKT_FETCH_DATA:
ok = make_fetch_response(buf, &response,
@@ -88,6 +91,17 @@ static int handle_packet(int sockfd,
return 0;
}
+static void init_protoverse_server(struct protoverse_server *server)
+{
+ init_resource_manager(&server->env.entities, sizeof(struct entity),
+ 1024, MAX_ENTITIES, "entity");
+}
+
+static void free_protoverse_server(struct protoverse_server *server)
+{
+ destroy_resource_manager(&server->env.entities);
+}
+
int protoverse_serve(struct protoverse_server *server)
{
#define FILEBUF_SIZE 31457280
@@ -105,6 +119,9 @@ int protoverse_serve(struct protoverse_server *server)
buf_ = malloc(FILEBUF_SIZE);
make_cursor(buf_, buf_ + FILEBUF_SIZE, &buf);
+ /* initialize object storage, etc */
+ init_protoverse_server(server);
+
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
printf("socket creation failed: %s\n", strerror(errno));
return 0;
@@ -133,14 +150,15 @@ int protoverse_serve(struct protoverse_server *server)
continue;
}
- ok = handle_packet(fd, &buf, &from, &packet);
+ ok = handle_packet(fd, &server->env, &buf, &from, &packet);
if (!ok) {
printf("handle packet failed for ");
- print_packet(&packet);
+ print_packet(&server->env, &packet);
}
buf.p = buf.start;
}
free(buf_);
+ free_protoverse_server(server);
}
diff --git a/src/serve.h b/src/serve.h
@@ -7,10 +7,12 @@
struct sockaddr_in *from,
struct packet *packet);
*/
+#include "env.h"
struct protoverse_server {
const char *bind;
int port;
+ struct env env;
/*
void *closure;
diff --git a/src/test.c b/src/test.c
@@ -21,6 +21,7 @@ static void print_mem(unsigned char *a, int len)
static void test_packet_serialization(struct packet packet)
{
struct packet packet_out;
+ struct env env;
int pushed[2], pulled;
int i;
@@ -45,15 +46,14 @@ static void test_packet_serialization(struct packet packet)
assert(!memcmp(bufs[0], bufs[2], pulled));
assert(packet_eq(&packet, &packet_out));
- print_packet(&packet);
+ print_packet(&env, &packet);
}
static void test_chat_packet_serialization(void)
{
struct packet packet;
- packet.type = PKT_CHAT;
- packet.data.chat.sender = 0xFFFF;
- packet.data.chat.message = "hello there";
+ packet.type = PKT_MESSAGE;
+ packet.data.message.message = "hello there";
printf("chat packet\n");
test_packet_serialization(packet);
diff --git a/src/types.h b/src/types.h
@@ -0,0 +1,17 @@
+
+#ifndef PROTOVERSE_TYPES_H
+#define PROTOVERSE_TYPES_H
+
+typedef unsigned char u8;
+typedef signed char s8;
+
+typedef unsigned short u16;
+typedef signed short s16;
+
+typedef unsigned int u32;
+typedef signed int s32;
+
+typedef unsigned long long u64;
+typedef signed long long s64;
+
+#endif /* PROTOVERSE_TYPES_H */
diff --git a/src/wasm.c b/src/wasm.c
@@ -62,7 +62,7 @@ static void log_dbg_(const char *fmt, ...)
#define log_dbg(...)
#endif
-static int is_valtype(unsigned char byte)
+static inline int is_valtype(unsigned char byte)
{
switch ((enum valtype)byte) {
case i32:
@@ -95,7 +95,7 @@ static int stack_pushval(struct cursor *cur, struct val *val)
return push_byte(cur, (unsigned char)val->type);
}
-static int cursor_popbyte(struct cursor *cur, unsigned char *byte)
+static inline int cursor_popbyte(struct cursor *cur, unsigned char *byte)
{
if (cur->p - 1 < cur->start)
return 0;
@@ -106,7 +106,7 @@ static int cursor_popbyte(struct cursor *cur, unsigned char *byte)
return 1;
}
-static int cursor_popdata(struct cursor *cur, unsigned char *dest, int len)
+static inline int cursor_popdata(struct cursor *cur, unsigned char *dest, int len)
{
if (cur->p - len < cur->start)
return 0;
diff --git a/todo/messages.gmi b/todo/messages.gmi
@@ -0,0 +1,16 @@
+
+# General verbs
+
+* Interact
+
+# Probe object verbs
+
+"describe" message
+
+* list object capabilities and messages
+
+## Example
+
+> describe lamp
+
+actions: switch
diff --git a/todo/todo.txt b/todo/todo.txt