]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Execution model and interrupt handling redesign
authorElias Fleckenstein <eliasfleckenstein@web.de>
Thu, 25 Mar 2021 11:56:25 +0000 (12:56 +0100)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Thu, 25 Mar 2021 11:56:25 +0000 (12:56 +0100)
19 files changed:
src/Makefile
src/array.c
src/array.h
src/client.c
src/client.h
src/clientcommands.c
src/list.c
src/map.c
src/map.h
src/mapblock_meshgen.c [new file with mode: 0644]
src/mapblock_meshgen.h [new file with mode: 0644]
src/mesh.c
src/mesh.h
src/network.c
src/scene.c [new file with mode: 0644]
src/scene.h [new file with mode: 0644]
src/server.c
src/server.h
src/servercommands.c

index 84067ac86c8f5815c94b7df47640b2831eccfebe..2649c590207b7ff9cf8970d993889855f6cd6ac2 100644 (file)
@@ -1,6 +1,6 @@
 COMMON = array.o binsearch.o list.o map.o signal.o util.o types.o
 SERVER = $(COMMON) server.o servercommands.o
-CLIENT = $(COMMON) client.o clientcommands.o mesh.o
+CLIENT = $(COMMON) client.o clientcommands.o mesh.o scene.o
 LIBRARIES = -lpthread -lm
 CLIENT_LIBRARIES = -lGL -lGLEW -lglfw
 FLAGS = -g
index de7733bb899543974e4f5751cfa7f56b7ee047b8..a6678e6eb1be940f1549d82afbb87a940cf1bea1 100644 (file)
@@ -6,7 +6,7 @@ static void array_realloc(Array *array)
 {
        if (array->siz > array->cap) {
                array->cap = array->siz + ARRAY_REALLOC_EXTRA;
-               array->ptr = realloc(array->ptr, array->cap * sizeof(void *));
+               array->ptr = realloc(array->ptr, array->cap * array->membsiz);
        }
 }
 
@@ -21,9 +21,9 @@ void array_insert(Array *array, void *elem, size_t idx)
        size_t oldsiz = array->siz;
        array_alloc(array, 1);
 
-       void **iptr = array->ptr + idx;
-       memmove(iptr + 1, iptr, (oldsiz - idx) * sizeof(void *));
-       *iptr = elem;
+       char *iptr = (char *) array->ptr + idx * array->membsiz;
+       memmove(iptr + array->membsiz, iptr, (oldsiz - idx) * array->membsiz);
+       memcpy(iptr, elem, array->membsiz);
 }
 
 void array_append(Array *array, void *elem)
@@ -31,10 +31,15 @@ void array_append(Array *array, void *elem)
        size_t oldsiz = array->siz;
        array_alloc(array, 1);
 
-       array->ptr[oldsiz] = elem;
+       memcpy((char *) array->ptr + oldsiz * array->membsiz, elem, array->membsiz);
 }
 
-Array array_create()
+Array array_create(size_t membsiz)
 {
-       return (Array) {0, 0, NULL};
+       return (Array) {
+               .membsiz = membsiz,
+               .siz = 0,
+               .cap = 0,
+               .ptr = NULL,
+       };
 }
index c0b42b50a2ee76b1220d6cf6e18d377b2827fd9f..71ef312955a9d278924bfc1d4b3dacaa3407db03 100644 (file)
@@ -7,12 +7,13 @@
 
 typedef struct
 {
+       size_t membsiz;
        size_t siz, cap;
-       void **ptr;
+       void *ptr;
 } Array;
 
 void array_insert(Array *array, void *elem, size_t idx);
 void array_append(Array *array, void *elem);
-Array array_create();
+Array array_create(size_t membsiz);
 
 #endif
index 328dffcd1e7883c7c0606cfb1e86861da6e78746..2067463ab4219f58459acf0f33df06e13c5f35ad 100644 (file)
 #include <unistd.h>
 #include <errno.h>
 #include <netdb.h>
-#include <GLFW/glfw3.h>
 #include <GL/glew.h>
 #include <GL/gl.h>
+#include <GLFW/glfw3.h>
 #include "client.h"
-#include "mesh.h"
 #include "signal.h"
 #include "util.h"
 
-void client_create_mesh(Client *client, Mesh *mesh);
-{
-       pthread_mutex_lock(client->meshlist_mtx);
-       list_put(&client->meshlist, mesh, NULL);
-       pthread_mutex_unlock(client->meshlist_mtx);
-}
+Client client;
 
-void client_remove_mesh(Client *client, Mesh *mesh);
+void client_disconnect(bool send, const char *detail)
 {
-       pthread_mutex_lock(client->meshlist_mtx);
-       list_delete(&client->meshlist, mesh);
-       pthread_mutex_unlock(client->meshlist_mtx);
-       delete_mesh(mesh);
-}
-
-void client_mapblock_changed(Client *client, v3s32 pos)
-{
-       v3s32 *posptr = malloc(sizeof(v3s32));
-       *posptr = pos;
-       pthread_mutex_lock(client->mapblock_meshgen_mtx);
-       if (! list_put(&client->mapblock_meshgen_queue, posptr, NULL))
-               free(posptr);
-       pthread_mutex_unlock(client->mapblock_meshgen_mtx);
-}
-
-void client_disconnect(Client *client, bool send, const char *detail)
-{
-       pthread_mutex_lock(client->write_mtx);
-       if (client->state != CS_DISCONNECTED) {
+       pthread_mutex_lock(&client.mtx);
+       if (client.state != CS_DISCONNECTED) {
                if (send)
-                       write_u32(client->fd, SC_DISCONNECT);
+                       write_u32(client.fd, SC_DISCONNECT);
 
-               client->state = CS_DISCONNECTED;
+               client.state = CS_DISCONNECTED;
                printf("Disconnected %s%s%s\n", INBRACES(detail));
-               close(client->fd);
+               close(client.fd);
        }
-       pthread_mutex_unlock(client->write_mtx);
+       pthread_mutex_unlock(&client.mtx);
 }
 
 #include "network.c"
 
-static void *reciever_thread(void *cliptr)
+static void *reciever_thread(void *unused)
 {
-       Client *client = cliptr;
-
-       handle_packets(client);
+       (void) unused;
 
-       if (errno == EINTR)
-               client_disconnect(client, true, NULL);
-       else
-               client_disconnect(client, false, "network error");
+       handle_packets(&client);
 
-       if (client->name)
-               free(client->name);
+       if (errno != EINTR)
+               client_disconnect(false, "network error");
 
-       pthread_mutex_lock(client->meshlist_mtx);
-       ITERATE_LIST(&client->meshes, pair) delete_mesh(pair->value);
-       list_clear(&client->meshes);
-       pthread_mutex_unlock(client->meshlist_mtx);
-
-       for (int i = 0; i < CLIENT_MTX_COUNT; i++)
-               pthread_mutex_destroy(&client.mutexes[i]);
-
-       exit(EXIT_SUCCESS);
        return NULL;
 }
 
-static void *mapblock_meshgen_thread(void *cliptr)
-{
-       Client *client = cliptr;
-
-       for ever {
-               ListPair **lptr = &client->mapblock_meshgen_queue.first;
-               if (*lptr) {
-                       MapBlock *block = map_get_block(client->map, *(v3s32 *)(*lptr)->key, false);
-                       Array vertices(sizeof(GLfloat));
-
-                       // ToDo: Actual vertices generation code
-
-                       client_create_mesh(client, create_mesh(vertices.ptr, vertices.siz));
-                       pthread_mutex_lock(client->mapblock_meshgen_mtx);
-                       *lptr = (*lptr)->next;
-                       pthread_mutex_unlock(client->mapblock_meshgen_mtx);
-               } else {
-                       sched_yield();
-               }
-       }
-}
-
-static void client_loop(Client *client)
+static void client_loop()
 {
        if(! glfwInit()) {
                printf("Failed to initialize GLFW\n");
@@ -128,38 +68,44 @@ static void client_loop(Client *client)
                return;
        }
 
-       while (! glfwWindowShouldClose(window) && client->state != CS_DISCONNECTED && ! interrupted) {
+       int shader_program = 0;
+
+       while (! glfwWindowShouldClose(window) && client.state != CS_DISCONNECTED && ! interrupted) {
                glClear(GL_COLOR_BUFFER_BIT);
                glClearColor(0.52941176470588, 0.8078431372549, 0.92156862745098, 1.0);
 
+               mat4x4 view, proj;
+
+               scene_render(client.scene, shader_program, view, proj);
+
                glfwSwapBuffers(window);
                glfwPollEvents();
        }
 }
 
-static bool client_name_prompt(Client *client)
+static bool client_name_prompt()
 {
        printf("Enter name: ");
        fflush(stdout);
        char name[NAME_MAX];
        if (scanf("%s", name) == EOF)
                return false;
-       client->name = strdup(name);
-       pthread_mutex_lock(client->write_mtx);
-       if (write_u32(client->fd, SC_AUTH) && write(client->fd, client->name, strlen(name) + 1)) {
-               client->state = CS_AUTH;
+       client.name = strdup(name);
+       pthread_mutex_lock(&client.mtx);
+       if (write_u32(client.fd, SC_AUTH) && write(client.fd, client.name, strlen(client.name) + 1)) {
+               client.state = CS_AUTH;
                printf("Authenticating...\n");
        }
-       pthread_mutex_unlock(client->write_mtx);
+       pthread_mutex_unlock(&client.mtx);
        return true;
 }
 
-static bool client_authenticate(Client *client)
+static bool client_authenticate()
 {
        for ever {
-               switch (client->state) {
+               switch (client.state) {
                        case CS_CREATED:
-                               if (client_name_prompt(client))
+                               if (client_name_prompt())
                                        break;
                                else
                                        return false;
@@ -178,11 +124,33 @@ static bool client_authenticate(Client *client)
        return false;
 }
 
-static bool compare_positions(void *p1, void *p2)
+static void client_start(int fd)
 {
-       v3s32 *pos1 = p1;
-       v3s32 *pos2 = p2;
-       return pos1->x == pos2->x && pos1->y == pos2->y && pos->z == pos2->z;
+       client.fd = fd;
+       pthread_mutex_init(&client.mtx, NULL);
+       client.state = CS_CREATED;
+       client.name = NULL;
+       client.map = map_create();
+       client.scene = scene_create();
+       //client.mapblock_meshgen = mapblock_meshgen_create();
+
+       pthread_t recv_thread;
+       pthread_create(&recv_thread, NULL, &reciever_thread, NULL);
+
+       if (client_authenticate())
+               client_loop();
+
+       if (client.state != CS_DISCONNECTED)
+               client_disconnect(true, NULL);
+
+       if (client.name)
+               free(client.name);
+
+       map_delete(client.map);
+       scene_delete(client.scene);
+       //mapblock_meshgen_delete(client.mapblock_meshgen);
+
+       pthread_mutex_destroy(&client.mtx);
 }
 
 int main(int argc, char **argv)
@@ -193,7 +161,7 @@ int main(int argc, char **argv)
                internal_error("missing address or port");
 
        struct addrinfo hints = {
-               .ai_family = AF_UNSPEC,                 // support both IPv4 and IPv6
+               .ai_family = AF_UNSPEC,
                .ai_socktype = SOCK_STREAM,
                .ai_protocol = 0,
                .ai_flags = AI_NUMERICSERV,
@@ -206,28 +174,12 @@ int main(int argc, char **argv)
        if (gai_state != 0)
                internal_error(gai_strerror(gai_state));
 
-       Client client = {
-               .fd = -1,
-               .map = NULL,
-               .name = NULL,
-               .state = CS_CREATED,
-               .meshlist = list_create(NULL),
-               .mapblock_meshgen_queue = list_create(&compare_positions),
-       };
-
-       for (int i = 0; i < CLIENT_MTX_COUNT; i++)
-               pthread_mutex_init(&client.mutexes[i], NULL);
-
-       client.write_mtx = &client.mutexes[0];
-       client.meshlist_mtx = &client.mutexes[1];
-       client.mapblock_meshgen_mtx = &client.mutexes[2];
+       int fd = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
 
-       client.fd = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
-
-       if (client.fd == -1)
+       if (fd == -1)
                syscall_error("socket");
 
-       if (connect(client.fd, info->ai_addr, info->ai_addrlen) == -1)
+       if (connect(fd, info->ai_addr, info->ai_addrlen) == -1)
                syscall_error("connect");
 
        char *addrstr = address_string((struct sockaddr_in6 *) info->ai_addr);
@@ -237,18 +189,7 @@ int main(int argc, char **argv)
        freeaddrinfo(info);
 
        init_signal_handlers();
+       client_start(fd);
 
-       client.map = map_create();
-
-       pthread_t recv_thread;
-       pthread_t mmg_thread;
-       pthread_create(&recv_thread, NULL, &reciever_thread, &client);
-       pthread_create(&mmg_thread, NULL, &mapblock_meshgen_thread, &client);
-
-       if (client_authenticate(&client))
-               client_loop(&client);
-
-       client_disconnect(&client, true, NULL);
-
-       pthread_join(recv_thread, NULL);
+       return EXIT_SUCCESS;
 }
index d2c001a2075707ca785958e4081ca759c1c9b293..bfc2900e6a843127118a1ad50495ac519e3a2e51 100644 (file)
@@ -6,28 +6,21 @@
 #include "servercommands.h"
 #include "clientcommands.h"
 #include "network.h"
-#include "list.h"
 #include "map.h"
-
-#define CLIENT_MTX_COUNT 3
+//#include "mapblock_meshgen.h"
+#include "scene.h"
 
 typedef struct Client
 {
        int fd;
+       pthread_mutex_t mtx;
+       ClientState state;
        char *name;
        Map *map;
-       ClientState state;
-       pthread_mutex_t *write_mtx;
-       pthread_mutex_t *meshlist_mtx;
-       pthread_mutex_t *mapblock_meshgen_mtx;
-       pthread_mutex_t mutexes[CLIENT_MTX_COUNT];
-       List meshlist;
-       List mapblock_meshgen_queue;
+       Scene *scene;
+       //MapblockMeshgen *mapblock_meshgen;
 } Client;
 
-void client_add_mesh(Client *client, Mesh *mesh);
-void client_remove_mesh(Client *client, Mesh *mesh);
-void client_mapblock_changed(Client *client, v3s32 pos);
-void client_disconnect(Client *client, bool send, const char *detail);
+void client_disconnect(bool send, const char *detail);
 
 #endif
index 3f0f224ecb157da989c0b8ee8120c4d7bcc7f851..4f68ffdf2754280bc4542b679133e39f54fb9dc4 100644 (file)
@@ -4,8 +4,10 @@
 
 static bool disconnect_handler(Client *client, bool good)
 {
+       (void) client;
+
        if (good)
-               client_disconnect(client, false, NULL);
+               client_disconnect(false, NULL);
        return true;
 }
 
@@ -37,7 +39,7 @@ static bool block_handler(Client *client, bool good)
                return false;
 
        if (good) {
-               client_mapblock_changed(client, block->pos);
+               //mapblock_meshgen_enqueue(client->mapblock_meshgen, block->pos);
                map_add_block(client->map, block);
        } else {
                map_free_block(block);
index 93163f77f377a7944d7b557ef40d4af81fb1b122..fa8af7078a34de049340f1e14471f2a526142f32 100644 (file)
@@ -1,13 +1,13 @@
 #include <stdlib.h>
 #include <string.h>
-#include "List.h"
+#include "list.h"
 
-int list_compare_default(void *v1, void *v2)
+bool list_compare_default(void *v1, void *v2)
 {
        return v1 == v2;
 }
 
-int list_compare_string(void *v1, void *v2)
+bool list_compare_string(void *v1, void *v2)
 {
        return strcmp(v1, v2) == 0;
 }
@@ -15,7 +15,7 @@ int list_compare_string(void *v1, void *v2)
 List list_create(ListComparator cmp)
 {
        return (List) {
-               .cmp = cmp ? cmp : list_compare_default;
+               .cmp = cmp ? cmp : list_compare_default,
                .first = NULL,
        };
 }
index 79f5aa127a57b0b8e407280aabf6053dc11da2c8..847b45342fbd839893a2e54b50fab1e1a3538d7f 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -5,6 +5,38 @@
 #include "map.h"
 #include "util.h"
 
+Map *map_create()
+{
+       Map *map = malloc(sizeof(Map));
+       map->sectors = array_create(sizeof(MapSector *));
+       return map;
+}
+
+static MapBlock **get_block_ptr(MapSector *sector, size_t idx)
+{
+       return (MapBlock **) sector->blocks.ptr + idx;
+}
+
+static MapSector **get_sector_ptr(Map *map, size_t idx)
+{
+       return (MapSector **) map->sectors.ptr + idx;
+}
+
+void map_delete(Map *map)
+{
+       for (size_t s = 0; s < map->sectors.siz; s++) {
+               MapSector *sector = *get_sector_ptr(map, s);
+               for (size_t b = 0; b < sector->blocks.siz; b++)
+                       map_free_block(*get_block_ptr(sector, b));
+               if (sector->blocks.ptr)
+                       free(sector->blocks.ptr);
+               free(sector);
+       }
+       if (map->sectors.ptr)
+               free(map->sectors.ptr);
+       free(map);
+}
+
 #define CMPBOUNDS(x) x == 0 ? 0 : x > 0 ? 1 : -1
 
 static s8 sector_compare(void *hash, void *sector)
@@ -19,16 +51,16 @@ MapSector *map_get_sector(Map *map, v2s32 pos, bool create)
        BinsearchResult res = binsearch(&hash, map->sectors.ptr, map->sectors.siz, &sector_compare);
 
        if (res.success)
-               return map->sectors.ptr[res.index];
+               return *get_sector_ptr(map, res.index);
        if (! create)
                return NULL;
 
        MapSector *sector = malloc(sizeof(MapSector));
        sector->pos = pos;
        sector->hash = hash;
-       sector->blocks = array_create();
+       sector->blocks = array_create(sizeof(MapBlock *));
 
-       array_insert(&map->sectors, sector, res.index);
+       array_insert(&map->sectors, &sector, res.index);
 
        return sector;
 }
@@ -39,7 +71,7 @@ static s8 block_compare(void *level, void *block)
        return CMPBOUNDS(d);
 }
 
-static void allocate_block(v3s23 pos)
+static MapBlock *allocate_block(v3s32 pos)
 {
        MapBlock *block = malloc(sizeof(MapBlock));
        block->pos = pos;
@@ -56,7 +88,7 @@ MapBlock *map_get_block(Map *map, v3s32 pos, bool create)
        BinsearchResult res = binsearch(&pos.y, sector->blocks.ptr, sector->blocks.siz, &block_compare);
 
        if (res.success)
-               return sector->blocks.ptr[res.index];
+               return *get_block_ptr(sector, res.index);
        if (! create)
                return NULL;
 
@@ -65,7 +97,7 @@ MapBlock *map_get_block(Map *map, v3s32 pos, bool create)
        MapNode air = map_node_create(NODE_AIR);
        ITERATE_MAPBLOCK block->data[x][y][z] = air;
 
-       array_insert(&sector->blocks, block, res.index);
+       array_insert(&sector->blocks, &block, res.index);
 
        return block;
 }
@@ -75,10 +107,11 @@ void map_add_block(Map *map, MapBlock *block)
        MapSector *sector = map_get_sector(map, (v2s32) {block->pos.x, block->pos.z}, true);
        BinsearchResult res = binsearch(&block->pos.y, sector->blocks.ptr, sector->blocks.siz, &block_compare);
        if (res.success) {
-               map_free_block(sector->blocks.ptr[res.index]);
-               sector->blocks.ptr[res.index] = block;
+               MapBlock **ptr = get_block_ptr(sector, res.index);
+               map_free_block(*ptr);
+               *ptr = block;
        } else {
-               array_insert(&sector->blocks, block, res.index);
+               array_insert(&sector->blocks, &block, res.index);
        }
 }
 
@@ -147,9 +180,9 @@ MapBlock *map_deserialize_block(int fd)
 bool map_serialize(int fd, Map *map)
 {
        for (size_t s = 0; s < map->sectors.siz; s++) {
-               MapSector *sector = map->sectors.ptr[s];
+               MapSector *sector = *get_sector_ptr(map, s);
                for (size_t b = 0; b < sector->blocks.siz; b++)
-                       if (! map_serialize_block(fd, sector->blocks.ptr[b]))
+                       if (! map_serialize_block(fd, *get_block_ptr(sector, b)))
                                return false;
        }
        return true;
@@ -198,26 +231,3 @@ void map_node_clear(MapNode *node)
 {
        list_clear(&node->meta);
 }
-
-Map *map_create()
-{
-       Map *map = malloc(sizeof(Map));
-       map->sectors = array_create();
-
-       return map;
-}
-
-void map_delete(Map *map)
-{
-       for (size_t s = 0; s < map->sectors.siz; s++) {
-               MapSector *sector = map->sectors.ptr[s];
-               for (size_t b = 0; b < sector->blocks.siz; b++)
-                       map_free_block(sector->blocks.ptr[b]);
-               if (sector->blocks.ptr)
-                       free(sector->blocks.ptr);
-               free(sector);
-       }
-       if (map->sectors.ptr)
-               free(map->sectors.ptr);
-       free(map);
-}
index 925b60f4710bcc2a294f7e397cbc7dd2b89c47cc..43f8cd3269c79d128303a8f42a7bfff86b28fe47 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -3,7 +3,7 @@
 
 #include <stdbool.h>
 #include "array.h"
-#include "linkedlist.h"
+#include "list.h"
 #include "node.h"
 #include "types.h"
 
@@ -12,7 +12,7 @@
 typedef struct
 {
        Node type;
-       LinkedList meta;
+       List meta;
 } MapNode;
 
 typedef struct
@@ -34,6 +34,9 @@ typedef struct
        Array sectors;
 } Map;
 
+Map *map_create();
+void map_delete(Map *map);
+
 MapSector *map_get_sector(Map *map, v2s32 pos, bool create);
 MapBlock *map_get_block(Map *map, v3s32 pos, bool create);
 
@@ -54,7 +57,4 @@ void map_set_node(Map *map, v3s32 pos, MapNode node);
 MapNode map_node_create(Node type);
 void map_node_clear(MapNode *node);
 
-Map *map_create();
-void map_delete(Map *map);
-
 #endif
diff --git a/src/mapblock_meshgen.c b/src/mapblock_meshgen.c
new file mode 100644 (file)
index 0000000..3c8ecf4
--- /dev/null
@@ -0,0 +1,76 @@
+static bool compare_positions(void *p1, void *p2)
+{
+       v3s32 *pos1 = p1;
+       v3s32 *pos2 = p2;
+       return pos1->x == pos2->x && pos1->y == pos2->y && pos->z == pos2->z;
+}
+
+static void *mapblock_meshgen_thread(void *cliptr)
+{
+       Client *client = cliptr;
+
+       for ever {
+               ListPair **lptr = &client->mapblock_meshgen_queue.first;
+               if (*lptr) {
+                       MapBlock *block = map_get_block(client->map, *(v3s32 *)(*lptr)->key, false);
+                       Array vertices(sizeof(GLfloat));
+
+                       ITERATE_MAPBLOCK {
+                               MapNode node = block->data[x][y][z];
+                               BlockDef *def = block->getDef();
+                               if (! def->drawable)
+                                       continue;
+                               ivec3 bpos(x, y, z);
+                               vec3 pos_from_mesh_origin = vec3(bpos) - vec3(SIZE / 2 + 0.5);
+                               for (int facenr = 0; facenr < 6; facenr++) {
+                                       ivec3 npos = bpos + face_dir[facenr];
+                                       const Block *neighbor_own, *neighbor;
+                                       neighbor_own = neighbor = getBlockNoEx(npos);
+                                       if (! neighbor)
+                                               neighbor = map->getBlock(pos * SIZE + npos);
+                                       if (neighbor && ! neighbor->getDef()->drawable)
+                                               any_drawable_block = true;
+                                       if (! mesh_created_before)
+                                               neighbor = neighbor_own;
+                                       if (! mesh_created_before && ! neighbor || neighbor && ! neighbor->getDef()->drawable) {
+                                               textures.push_back(def->tile_def.get(facenr));
+                                               for (int vertex_index = 0; vertex_index < 6; vertex_index++) {
+                                                       for (int attribute_index = 0; attribute_index < 5; attribute_index++) {
+                                                               GLdouble value = box_vertices[facenr][vertex_index][attribute_index];
+                                                               switch (attribute_index) {
+                                                                       case 0:
+                                                                       value += pos_from_mesh_origin.x;
+                                                                       break;
+                                                                       case 1:
+                                                                       value += pos_from_mesh_origin.y;
+                                                                       break;
+                                                                       case 2:
+                                                                       value += pos_from_mesh_origin.z;
+                                                                       break;
+                                                               }
+                                                               vertices.push_back(value);
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+                       client_create_mesh(client, create_mesh(vertices.ptr, vertices.siz));
+                       pthread_mutex_lock(client->mapblock_meshgen_mtx);
+                       *lptr = (*lptr)->next;
+                       pthread_mutex_unlock(client->mapblock_meshgen_mtx);
+               } else {
+                       sched_yield();
+               }
+       }
+}
+
+void client_mapblock_changed(Client *client, v3s32 pos)
+{
+       v3s32 *posptr = malloc(sizeof(v3s32));
+       *posptr = pos;
+       pthread_mutex_lock(client->mapblock_meshgen_mtx);
+       if (! list_put(&client->mapblock_meshgen_queue, posptr, NULL))
+               free(posptr);
+       pthread_mutex_unlock(client->mapblock_meshgen_mtx);
+}
diff --git a/src/mapblock_meshgen.h b/src/mapblock_meshgen.h
new file mode 100644 (file)
index 0000000..3501269
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _MAPBLOCK_MESHGEN_H_
+#define _MAPBLOCK_MESHGEN_H_
+
+typedef struct
+{
+       pthread_mutex_t mtx;
+} MapblockMeshgen;
+
+
+
+#endif
index 8d1c8b69c3fce7bea45c73efd06983e3c419a92f..6016c12e03e99392f2826edde97063f47baae970 100644 (file)
@@ -1 +1 @@
+#include "mesh.h"
index bfb80798475011a52ddae0645c21cd3cb65b44bf..de5aa2c706b29713a3872da96ff441ea83e22254 100644 (file)
@@ -13,7 +13,7 @@ typedef struct
        GLuint VAO, VBO;
 } Mesh;
 
-Mesh *create_mesh(const GLvoid *vertices, GLsizei size);
-void delete_mesh(Mesh *mesh);
+Mesh *mesh_create(const GLvoid *vertices, GLsizei size);
+void mesh_delete(Mesh *mesh);
 
 #endif
index 7c585b797bd1d91bf11bb2a1134adcde66f5dd50..5e0ecb881d85f44ebc7896f113bcf1666990b77d 100644 (file)
@@ -2,14 +2,14 @@
 
 bool send_command(Client *client, RemoteCommand cmd)
 {
-       pthread_mutex_lock(client->write_mtx);
+       pthread_mutex_lock(&client->mtx);
        bool ret = write_u32(client->fd, cmd);
-       pthread_mutex_unlock(client->write_mtx);
+       pthread_mutex_unlock(&client->mtx);
        return ret;
 }
 
 static void handle_packets(Client *client) {
-       while (client->state != CS_DISCONNECTED) {
+       while (client->state != CS_DISCONNECTED || ! interrupted) {
                struct pollfd pfd = {
                        .fd = client->fd,
                        .events = POLLIN,
@@ -23,11 +23,10 @@ static void handle_packets(Client *client) {
                        return;
                }
 
-               if (client->state == CS_DISCONNECTED)
-                       return;
-
-               if (pstate == 0)
+               if (pstate == 0) {
+                       sched_yield();
                        continue;
+               }
 
                if (! (pfd.revents & POLLIN))
                        return;
diff --git a/src/scene.c b/src/scene.c
new file mode 100644 (file)
index 0000000..9362b54
--- /dev/null
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+#include "scene.h"
+
+Scene *scene_create()
+{
+       Scene *scene = malloc(sizeof(Scene));
+       scene->meshes = list_create(NULL),
+       pthread_mutex_init(&scene->mtx, NULL);
+
+       return scene;
+}
+
+void scene_delete(Scene *scene)
+{
+       ITERATE_LIST(&scene->meshes, pair) mesh_delete(pair->value);
+       list_clear(&scene->meshes);
+       pthread_mutex_destroy(&scene->mtx);
+       free(scene);
+}
+
+void scene_add_mesh(Scene *scene, Mesh *mesh)
+{
+       list_put(&scene->meshes, mesh, NULL);
+}
+
+void scene_remove_mesh(Scene *scene, Mesh *mesh)
+{
+       pthread_mutex_lock(&scene->mtx);
+       list_delete(&scene->meshes, mesh);
+       pthread_mutex_unlock(&scene->mtx);
+       mesh_delete(mesh);
+}
+
diff --git a/src/scene.h b/src/scene.h
new file mode 100644 (file)
index 0000000..b1a48c3
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _SCENE_H_
+#define _SCENE_H_
+
+#include <pthread.h>
+#include "list.h"
+#include "mesh.h"
+
+typedef struct
+{
+       List meshes;
+       pthread_mutex_t mtx;
+} Scene;
+
+Scene *scene_create();
+void scene_delete(Scene *scene);
+
+void scene_add_mesh(Scene *scene, Mesh *mesh);
+void scene_remove_mesh(Scene *scene, Mesh *mesh);
+void scene_render(Scene *scene, int prog, mat4x4 view, mat4x4 proj);   // ToDo
+
+#endif
index c160dd72f36479b208104276bba77a23507aa708..3cde37ce7a3822f73e78d04cf49158745d79cbc5 100644 (file)
@@ -3,17 +3,18 @@
 #include <unistd.h>
 #include <errno.h>
 #include <netdb.h>
-#include <fcntl.h>
 #include "server.h"
 #include "signal.h"
 #include "util.h"
 
+Server server;
+
 void server_disconnect_client(Client *client, int flags, const char *detail)
 {
        client->state = CS_DISCONNECTED;
 
        if (client->name && ! (flags & DISCO_NO_REMOVE))
-               list_delete(&client->server->clients, client->name);
+               list_delete(&server.clients, client->name);
 
        if (! (flags & DISCO_NO_MESSAGE))
                printf("Disconnected %s %s%s%s\n", client->name, INBRACES(detail));
@@ -21,40 +22,14 @@ void server_disconnect_client(Client *client, int flags, const char *detail)
        if (! (flags & DISCO_NO_SEND))
                send_command(client, CC_DISCONNECT);
 
-       pthread_mutex_lock(client->write_mtx);
+       pthread_mutex_lock(&client->mtx);
        close(client->fd);
-       pthread_mutex_unlock(client->write_mtx);
-}
-
-void server_shutdown(Server *srv)
-{
-       printf("Shutting down\n");
-
-       ITERATE_LIST(&srv->clients, pair) server_disconnect_client(pair->value, DISCO_NO_REMOVE | DISCO_NO_MESSAGE, "");
-       list_clear(&srv->clients);
-
-       shutdown(srv->sockfd, SHUT_RDWR);
-       close(srv->sockfd);
-
-       FILE *mapfile = fopen("map", "w");
-       if (mapfile) {
-               if (map_serialize(fileno(mapfile), srv->map))
-                       printf("Saved map\n");
-               else
-                       perror("map_serialize");
-               fclose(mapfile);
-       } else {
-               perror("fopen");
-       }
-
-       map_delete(srv->map);
-
-       exit(EXIT_SUCCESS);
+       pthread_mutex_unlock(&client->mtx);
 }
 
 #include "network.c"
 
-static void *reciever_thread(void *clientptr)
+static void *server_reciever_thread(void *clientptr)
 {
        Client *client = clientptr;
 
@@ -68,40 +43,77 @@ static void *reciever_thread(void *clientptr)
 
        free(client->address);
 
-       pthread_mutex_destroy(client->write_mtx);
+       pthread_mutex_destroy(&client->mtx);
+
        free(client);
 
        return NULL;
 }
 
-static void accept_client(Server *srv)
+static void server_accept_client()
 {
        struct sockaddr_storage client_address = {0};
        socklen_t client_addrlen = sizeof(client_address);
 
-       int fd = accept(srv->sockfd, (struct sockaddr *) &client_address, &client_addrlen);
+       int fd = accept(server.sockfd, (struct sockaddr *) &client_address, &client_addrlen);
 
        if (fd == -1) {
-               if (errno == EINTR)
-                       server_shutdown(srv);
-               else
-                       syscall_error("accept");
+               if (errno != EINTR)
+                       perror("accept");
+               return;
        }
 
        Client *client = malloc(sizeof(Client));
-       client->server = srv;
-       client->state = CS_CREATED;
        client->fd = fd;
+       pthread_mutex_init(&client->mtx, NULL);
+       client->state = CS_CREATED;
        client->address = address_string((struct sockaddr_in6 *) &client_address);
        client->name = client->address;
+       client->server = &server;
+       pthread_create(&client->thread, NULL, &server_reciever_thread, client);
 
        printf("Connected %s\n", client->address);
+}
+
+void server_start(int fd)
+{
+       server.sockfd = fd;
+       server.map = map_create(NULL);
+       server.clients = list_create(&list_compare_string);
+
+       FILE *mapfile = fopen("map", "r");
+       if (mapfile) {
+               map_deserialize(fileno(mapfile), server.map);
+               fclose(mapfile);
+       } else if (errno != ENOENT) {
+               perror("fopen");
+       }
+
+       while (! interrupted)
+               server_accept_client();
+
+       printf("Shutting down\n");
+
+       ITERATE_LIST(&server.clients, pair) server_disconnect_client(pair->value, DISCO_NO_REMOVE | DISCO_NO_MESSAGE, "");
+       list_clear(&server.clients);
 
-       client->write_mtx = &client->mutex;
-       pthread_mutex_init(client->write_mtx, NULL);
+       shutdown(server.sockfd, SHUT_RDWR);
+       close(server.sockfd);
 
-       pthread_t thread;
-       pthread_create(&thread, NULL, &reciever_thread, client);
+       mapfile = fopen("map", "w");
+       if (mapfile) {
+               if (map_serialize(fileno(mapfile), server.map))
+                       printf("Saved map\n");
+               else
+                       perror("map_serialize");
+               fclose(mapfile);
+       } else {
+               perror("fopen");
+       }
+
+       map_delete(server.map);
+
+       exit(EXIT_SUCCESS);
 }
 
 int main(int argc, char **argv)
@@ -125,26 +137,20 @@ int main(int argc, char **argv)
        if (gai_state != 0)
                internal_error(gai_strerror(gai_state));
 
-       Server server = {
-               .sockfd = -1,
-               .map = NULL,
-               .clients = list_create(&list_compare_string),
-       };
-
-       server.sockfd = socket(info->ai_family, info->ai_socktype, 0);
+       int fd = socket(info->ai_family, info->ai_socktype, 0);
 
-       if (server.sockfd == -1)
+       if (fd == -1)
                syscall_error("socket");
 
        int flag = 1;
 
-       if (setsockopt(server.sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, 4) == -1)
+       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) == -1)
                syscall_error("setsockopt");
 
-       if (bind(server.sockfd, info->ai_addr, info->ai_addrlen) == -1)
+       if (bind(fd, info->ai_addr, info->ai_addrlen) == -1)
                syscall_error("bind");
 
-       if (listen(server.sockfd, 3) == -1)
+       if (listen(fd, 3) == -1)
                syscall_error("listen");
 
        char *addrstr = address_string((struct sockaddr_in6 *) info->ai_addr);
@@ -154,16 +160,7 @@ int main(int argc, char **argv)
        freeaddrinfo(info);
 
        init_signal_handlers();
+       server_start(fd);
 
-       server.map = map_create(NULL);
-
-       FILE *mapfile = fopen("map", "r");
-       if (mapfile) {
-               map_deserialize(fileno(mapfile), server.map);
-               fclose(mapfile);
-       } else if (errno != ENOENT) {
-               perror("fopen");
-       }
-
-       for ever accept_client(&server);
+       return EXIT_SUCCESS;
 }
index 736cc74dc30edc403cf9f778c96f881a6c178f37..72c0f4ba3f328342508b128ad6bb734d46e1180e 100644 (file)
 typedef struct
 {
        int sockfd;
-       Map *map;
        List clients;
+       Map *map;
 } Server;
 
 typedef struct Client
 {
        int fd;
-       char *name;
+       pthread_mutex_t mtx;
+       ClientState state;
        char *address;
+       char *name;
        Server *server;
-       ClientState state;
-       pthread_mutex_t *write_mtx;
-       pthread_mutex_t mutex;
+       pthread_t thread;
 } Client;
 
 typedef enum
@@ -35,6 +35,6 @@ typedef enum
 } DiscoFlag;
 
 void server_disconnect_client(Client *client, int flags, const char *detail);
-void server_shutdown(Server *srv);
+void server_shutdown();
 
 #endif
index bdb8a6d8e1dc7f38443e84228f807d797345f5a9..39457a093a3d9f40a1a39174f269a915bb38b9f3 100644 (file)
@@ -33,9 +33,9 @@ static bool auth_handler(Client *client, bool good)
                free(name);
        }
 
-       pthread_mutex_lock(client->write_mtx);
+       pthread_mutex_lock(&client->mtx);
        bool ret = write_u32(client->fd, CC_AUTH) && write_u8(client->fd, success);
-       pthread_mutex_unlock(client->write_mtx);
+       pthread_mutex_unlock(&client->mtx);
 
        return ret;
 }
@@ -52,9 +52,9 @@ static bool getblock_handler(Client *client, bool good)
 
        MapBlock *block = map_get_block(client->server->map, pos, false);
        if (block) {
-               pthread_mutex_lock(client->write_mtx);
+               pthread_mutex_lock(&client->mtx);
                bool ret = write_u32(client->fd, CC_BLOCK) && map_serialize_block(client->fd, block);
-               pthread_mutex_unlock(client->write_mtx);
+               pthread_mutex_unlock(&client->mtx);
 
                return ret;
        }