protoverse

A metaverse protocol
git clone git://jb55.com/protoverse
Log | Files | Refs | README | LICENSE

protoverse.c (4344B)


      1 
      2 #include "io.h"
      3 #include "parse.h"
      4 #include "describe.h"
      5 #include "serve.h"
      6 #include "client.h"
      7 #include "wasm.h"
      8 #include "resource.h"
      9 #include "entity.h"
     10 
     11 #include <assert.h>
     12 #include <stdlib.h>
     13 #include <string.h>
     14 #include <sys/mman.h>
     15 
     16 #define MAX_ENTITIES 1048576
     17 #define streq(a, b) strcmp(a,b) == 0
     18 
     19 /*
     20 static void print_all_cells(struct parser *parser)
     21 {
     22 	struct cell *cell;
     23 	int i, j;
     24 	int ncells;
     25 
     26 	ncells = cursor_count(parser->cells, sizeof(struct cell));
     27 	printf("ncells %d\n", ncells);
     28 	for (i = 0; i < ncells; i++) {
     29 		cell = get_cell(parser->cells, i);
     30 		print_cell(parser->attributes, cell);
     31 		printf("\n");
     32 
     33 		for (j = 0; j < cell->n_children; j++) {
     34 			cell = get_cell(parser->cells, cell->children[j]);
     35 			assert(cell);
     36 			printf("  ");
     37 			print_cell(parser->attributes, cell);
     38 			printf("\n");
     39 		}
     40 	}
     41 }
     42 */
     43 
     44 static int match_selector(struct cursor *attrs, struct cell *cell, const char *query)
     45 {
     46 	const char *str;
     47 	int str_len;
     48 	int query_len = strlen(query);
     49 
     50 	if (!cell_attr_str(attrs, cell, &str, &str_len, A_NAME))
     51 		return 0;
     52 	if (query_len == str_len && !memcmp(str, query, str_len))
     53 		return 1;
     54 	if (!cell_attr_str(attrs, cell, &str, &str_len, A_ID))
     55 		return 0;
     56 	if (query_len == str_len && !memcmp(str, query, str_len))
     57 		return 1;
     58 
     59 	return 0;
     60 }
     61 
     62 static int cell_selector(struct parser *parser, u32 root, const char *query)
     63 {
     64 	int res;
     65 	int i;
     66 	struct cell *cell = get_cell(&parser->cells, root);
     67 
     68 	if ((res = match_selector(&parser->attributes, cell, query)))
     69 		return root;
     70 
     71 	for (i = 0; i < cell->n_children; i++) {
     72 		//cell = get_cell(&parser->cells, cell->children[i]);
     73 		if ((res = cell_selector(parser, cell->children[i], query)))
     74 			return res;
     75 	}
     76 
     77 	return 0;
     78 }
     79 
     80 static int print_cell_tree(struct parser *parser, u32 root, int depth)
     81 {
     82 	int i;
     83 
     84 
     85 	struct cell *cell = get_cell(&parser->cells, root);
     86 	if (!cell) {
     87 		printf("no root cell...\n");
     88 		return 0;
     89 	}
     90 
     91 	/*  sanity TODO: configurable max depth */
     92 	if (depth > 255)
     93 		return 0;
     94 
     95 	for (i = 0; i < depth; i++) {
     96 		printf("  ");
     97 	}
     98 
     99 	print_cell(&parser->attributes, cell);
    100 	printf("\n");
    101 
    102 	for (i = 0; i < cell->n_children; i++) {
    103 		print_cell_tree(parser, cell->children[i], depth+1);
    104 	}
    105 
    106 
    107 	return 1;
    108 }
    109 
    110 static void init_protoverse_server(struct protoverse_server *server)
    111 {
    112 	(void)server;
    113 	/*
    114 	init_resource_manager(&server->env.entities, sizeof(struct entity),
    115 			1024, MAX_ENTITIES, "entity");
    116 			*/
    117 }
    118 
    119 static void free_protoverse_server(struct protoverse_server *server)
    120 {
    121 	(void)server;
    122 	//destroy_resource_manager(&server->env.entities);
    123 }
    124 
    125 static int usage(void)
    126 {
    127 	printf("usage: protoverse <command> [args]\n\n");
    128 	printf("   COMMANDS\n\n");
    129 	printf("       parse file.space\n");
    130 	printf("       serve file.space\n");
    131 	printf("       client\n");
    132 	printf("       run code.wasm\n");
    133 
    134 	return 1;
    135 }
    136 
    137 
    138 extern char **environ;
    139 
    140 int main(int argc, const char *argv[])
    141 {
    142 	const int buflen = 10000000;
    143 	u8 *buf = malloc(buflen);
    144 	char **env = environ;
    145 	const char *space, *code_file;
    146 	const char *cmd;
    147 	unsigned char *wasm_data;
    148 	struct parser parser;
    149 	struct protoverse_server server;
    150 	int root, found;
    151 	int ok;
    152 	int retval;
    153 	size_t len;
    154 
    155 	if (argc < 2)
    156 		return usage();
    157 
    158 	cmd = argv[1];
    159 
    160 	if (streq(cmd, "parse")) {
    161 		if (argc < 3)
    162 			return usage();
    163 		ok = init_parser(&parser);
    164 		if (!ok) {
    165 			printf("failed to initialize parser\n");
    166 			return 1;
    167 		}
    168 		space = argv[2];
    169 		ok = parse_file(&parser, space, &root, buf, buflen);
    170 		if (!ok) {
    171 			printf("failed to parse file\n");
    172 			return 1;
    173 		}
    174 
    175 		if (argc > 3) {
    176 			if ((found = cell_selector(&parser, root, argv[3])))
    177 				root = found;
    178 		}
    179 
    180 		//print_cell_tree(&parser, root, 0);
    181 
    182 		describe(&parser, root);
    183 		free_parser(&parser);
    184 	} else if (streq(cmd, "serve")) {
    185 		if (argc != 3)
    186 			return usage();
    187 		space = argv[2];
    188 		printf("serving protoverse on port 1988...\n");
    189 
    190 		server.port = 1988;
    191 		server.bind = "127.0.0.1";
    192 
    193 		init_protoverse_server(&server);
    194 		protoverse_serve(&server);
    195 		free_protoverse_server(&server);
    196 	} else if (streq(cmd, "client")) {
    197 		protoverse_connect("127.0.0.1", 1988);
    198 	} else if (streq(cmd, "run")) {
    199 		if (argc < 3)
    200 			return usage();
    201 		code_file = argv[2];
    202 		if (!map_file(code_file, &wasm_data, &len)) {
    203 			perror("mmap");
    204 			return 1;
    205 		}
    206 		run_wasm(wasm_data, len, argc - 2, argv + 2, env, &retval);
    207 		munmap(wasm_data, len);
    208 		return retval;
    209 	}
    210 
    211 	return 0;
    212 }