diff options
Diffstat (limited to 'ark/src')
| -rw-r--r-- | ark/src/soul.c | 198 | ||||
| -rw-r--r-- | ark/src/wl.c | 238 | ||||
| -rw-r--r-- | ark/src/world.c | 199 | ||||
| -rw-r--r-- | ark/src/world_load.c (renamed from ark/src/soul_load.c) | 22 |
4 files changed, 403 insertions, 254 deletions
diff --git a/ark/src/soul.c b/ark/src/soul.c deleted file mode 100644 index 4268cd5..0000000 --- a/ark/src/soul.c +++ /dev/null @@ -1,198 +0,0 @@ -#include "soul.h" - -#include <ctype.h> -#include <dlfcn.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <unistd.h> - -/* Utility function for showing the marshalled states as hex code */ -static void shx(uint8_t *state, uint32_t sz) -{ - uint32_t i = 0; - while (i < sz) { - for (int j = 0; j < 16; ++j) { - if (i < sz) { - printf("%02x ", (unsigned int)state[i]); - } - else { - printf(" "); - } - ++i; - } - - i -= 16; - - printf(" "); - - for (int j = 0; j < 16; ++j) { - if (i < sz) { - if (isprint(state[i]) && !isspace(state[i])) { - printf("%c", state[i]); - } - else { - printf("."); - } - } - else { - printf(" "); - } - ++i; - } - printf("\n"); - } -} - -int load_soul_from_dl_(dlhandle_t dl, soul_t *soul); - -static void lock(soul_t *soul) { pthread_mutex_lock(&soul->lock); }; - -static void unlock(soul_t *soul) { pthread_mutex_unlock(&soul->lock); }; - -static int load_soul_from_file_(int argc, char **argv, const char *filename, - soul_t *soul) -{ - dlhandle_t lib = dlopen(filename, RTLD_NOW | RTLD_GLOBAL); - int ec = 0; - - if (!lib) { - fprintf(stderr, "Failed to open library: %s: %s\n", filename, dlerror()); - ec = 1; - goto end; - } - - printf("Loading file.\n"); - ec = load_soul_from_dl_(lib, soul); - - if (ec) { - goto end; - } - - strncpy(soul->filename, filename, sizeof(soul->filename)); - soul->argc = argc; - soul->argv = argv; - - soul->arksoul_export_load(soul->argc, soul->argv); -end: - return ec; -} - -static void maybe_run_metaload(int argc, char **argv, soul_t *soul) -{ - static char *loaded_souls[12]; - int i; - for (i = 0; i < 12 && loaded_souls[i]; ++i) { - if (strcmp(loaded_souls[i], soul->soul_name) == 0) { - return; // Soul is already loaded - } - } - loaded_souls[i] = strdup(soul->soul_name); - - printf("First time loading %s, running metaload.\n", soul->soul_name); - if (soul->arksoul_export_metaload) { - soul->arksoul_export_metaload(argc, argv); - } -} - -int load_soul_from_file(int argc, char **argv, const char *filename, - soul_t *soul) -{ - memset(soul, 0, sizeof(*soul)); - - pthread_mutexattr_t attr; - if (pthread_mutexattr_init(&attr)) { - perror("pthread_mutexattr_init"); - return 1; - } - - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) { - perror("pthread_mutexattr_settype"); - return 1; - } - - if (pthread_mutex_init(&soul->lock, &attr)) { - pthread_mutexattr_destroy(&attr); - perror("pthread_mutexattr_init"); - return 1; - } - pthread_mutexattr_destroy(&attr); - int rc = load_soul_from_file_(argc, argv, filename, soul); - - if (rc == 0) { - maybe_run_metaload(argc, argv, soul); - } - - return rc; -} - -int soul_hot_reload_same_state(soul_t *soul) -{ - char filename_cpy[PATH_MAX]; - strncpy(filename_cpy, soul->filename, sizeof(filename_cpy)); - return soul_hot_reload(soul->argc, soul->argv, filename_cpy, soul); -} - -int soul_hot_reload(int argc, char **argv, const char *filepath, soul_t *soul) -{ - int ec = 0; - uint32_t sz = 0; - uint8_t *marshalled_state = NULL; - - printf("Hot Reloading %s\n", soul->soul_name); - lock(soul); - - printf("Marshalling state ...\n"); - marshalled_state = soul->arksoul_export_preserve(soul->state, &sz); - - printf("Calling teardown ...\n"); - soul->arksoul_export_release(soul->state); - - printf("State Marshalled:\n"); - shx(marshalled_state, sz); - - printf("Unloading old library handle.\n"); - if (dlclose(soul->library_handle)) { - printf("Could not close library handle: %s\n", dlerror()); - } - - if ((ec = load_soul_from_file_(argc, argv, filepath, soul))) { - goto fail; - } - - printf("Hot starting soul ...\n"); - soul->state = soul->arksoul_export_rebirth(soul, marshalled_state, sz); - -fail: - free(marshalled_state); - unlock(soul); - return ec; -} - -void soul_run_requested_actions(soul_t *soul) -{ - lock(soul); - requested_action_t requested_actions[MAX_QUEUED_ACTIONS]; - size_t n_requested_actions = soul->n_requested_actions; - memcpy(&requested_actions, soul->requested_actions, - sizeof(requested_actions)); - soul->n_requested_actions = 0; - unlock(soul); - - size_t i; - for (i = 0; i < n_requested_actions; ++i) { - requested_actions[i].action(soul, requested_actions[i].str_arg); - if (requested_actions[i].arg_dtor) { - requested_actions[i].arg_dtor(requested_actions[i].ptr_arg); - } - } -} - -void soul_cold_start(soul_t *soul) -{ - lock(soul); - soul->state = soul->arksoul_export_ensoul(soul); - unlock(soul); -} diff --git a/ark/src/wl.c b/ark/src/wl.c index b9ce952..fc0ddc7 100644 --- a/ark/src/wl.c +++ b/ark/src/wl.c @@ -9,8 +9,15 @@ #include "xdg-decoration-unstable-v1-client-protocol.h" -// This macro is responsible for calling a handler on a soul. This macro will -// acquire the soul's lock, call the member with the arguments and update the +#include <wlr/interfaces/wlr_buffer.h> + +#ifdef ARK_HAVE_CAIRO +#include <cairo.h> +#include <drm_fourcc.h> +#endif + +// This macro is responsible for calling a handler on a world. This macro will +// acquire the world's lock, call the member with the arguments and update the // state. // // This only works on function which have the format: @@ -18,15 +25,133 @@ // opqst_t function(args ..., opqst_t state); // // Note that the state parameter is omitted from this macro. -#define soul_call_update_state(soul, member, ...) \ +#define world_call_update_state(world, member, ...) \ do { \ - soul_t *sl__ = &(soul); \ + world_t *sl__ = &(world); \ pthread_mutex_lock(&sl__->lock); \ sl__->state = sl__->member(__VA_ARGS__, sl__->state); \ pthread_mutex_unlock(&sl__->lock); \ - soul_run_requested_actions(sl__); \ + world_run_requested_actions(sl__); \ } while (0) +#ifdef ARK_HAVE_CAIRO +struct montis_image_buffer { + struct wlr_buffer base; + cairo_surface_t *surface; + uint32_t drm_format; +}; + +static void image_buffer_destroy(struct wlr_buffer *wlr_buffer) +{ + struct montis_image_buffer *buffer = + wl_container_of(wlr_buffer, buffer, base); + cairo_surface_destroy(buffer->surface); + free(buffer); +} + +static bool image_buffer_begin_data_ptr_access(struct wlr_buffer *wlr_buffer, + uint32_t flags, void **data, + uint32_t *format, size_t *stride) +{ + if (flags & WLR_BUFFER_DATA_PTR_ACCESS_WRITE) { + return false; + } + struct montis_image_buffer *buffer = + wl_container_of(wlr_buffer, buffer, base); + cairo_surface_flush(buffer->surface); + *data = cairo_image_surface_get_data(buffer->surface); + *stride = cairo_image_surface_get_stride(buffer->surface); + *format = buffer->drm_format; + return true; +} + +static void image_buffer_end_data_ptr_access(struct wlr_buffer *wlr_buffer) {} + +static const struct wlr_buffer_impl image_buffer_impl = { + .destroy = image_buffer_destroy, + .begin_data_ptr_access = image_buffer_begin_data_ptr_access, + .end_data_ptr_access = image_buffer_end_data_ptr_access, +}; + +static struct wlr_buffer *load_background_buffer(const char *path) +{ + cairo_surface_t *surface = cairo_image_surface_create_from_png(path); + if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { + cairo_surface_destroy(surface); + wlr_log(WLR_ERROR, "failed to load background image: %s", path); + return NULL; + } + + cairo_format_t format = cairo_image_surface_get_format(surface); + uint32_t drm_format = DRM_FORMAT_ARGB8888; + if (format == CAIRO_FORMAT_RGB24) { + drm_format = DRM_FORMAT_XRGB8888; + } + else if (format != CAIRO_FORMAT_ARGB32) { + cairo_surface_destroy(surface); + wlr_log(WLR_ERROR, "unsupported background image format: %d", format); + return NULL; + } + + int width = cairo_image_surface_get_width(surface); + int height = cairo_image_surface_get_height(surface); + + struct montis_image_buffer *buffer = calloc(1, sizeof(*buffer)); + if (!buffer) { + cairo_surface_destroy(surface); + return NULL; + } + + wlr_buffer_init(&buffer->base, &image_buffer_impl, width, height); + buffer->surface = surface; + buffer->drm_format = drm_format; + return &buffer->base; +} +#else +static struct wlr_buffer *load_background_buffer(const char *path) +{ + (void)path; + wlr_log(WLR_ERROR, "backgrounds require cairo support"); + return NULL; +} +#endif + +static bool background_accepts_input(struct wlr_scene_buffer *buffer, + double *sx, double *sy) +{ + (void)buffer; + (void)sx; + (void)sy; + return false; +} + +static void output_update_background(struct montis_output *output) +{ + struct montis_server *server = output->server; + if (!server->background_buffer) { + return; + } + + if (!output->background) { + output->background = wlr_scene_buffer_create(&server->scene->tree, + server->background_buffer); + if (!output->background) { + wlr_log(WLR_ERROR, "failed to create background node"); + return; + } + output->background->point_accepts_input = background_accepts_input; + wlr_scene_node_lower_to_bottom(&output->background->node); + } + else { + wlr_scene_buffer_set_buffer(output->background, server->background_buffer); + } + + struct wlr_box box; + wlr_output_layout_get_box(server->output_layout, output->wlr_output, &box); + wlr_scene_node_set_position(&output->background->node, box.x, box.y); + wlr_scene_buffer_set_dest_size(output->background, box.width, box.height); +} + static void focus_toplevel(struct montis_toplevel *toplevel, struct wlr_surface *surface) { @@ -113,9 +238,9 @@ static void keyboard_handle_key(struct wl_listener *listener, void *data) if (nsyms > 0 && syms[0] >= XKB_KEY_XF86Switch_VT_1 && syms[0] <= XKB_KEY_XF86Switch_VT_12) { /* Escape-hatch to change sessions. These should always be available key - * bindings regardless of what the soul dictates. This allows an escape - * hatch to edit the soul in a different vterm and then use the escape - * hatch below to hot-restart the soul if things get borked. */ + * bindings regardless of what the world dictates. This allows an escape + * hatch to edit the world in a different vterm and then use the escape + * hatch below to hot-restart the world if things get borked. */ if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { wlr_session_change_vt(server->session, syms[0] - XKB_KEY_XF86Switch_VT_1 + 1); @@ -124,26 +249,26 @@ static void keyboard_handle_key(struct wl_listener *listener, void *data) else if (modifiers == (WLR_MODIFIER_SHIFT | WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT) && nsyms > 0 && syms[0] == XKB_KEY_Escape) { - /* Escape-hatch to hot-reload the soul in case the soul got borked and + /* Escape-hatch to hot-reload the world in case the world got borked and * stops accepting keybindings. Ctrl+Shift+Alt+Escape will always reload the - * soul. */ + * world. */ if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - if ((ec = soul_hot_reload_same_state(&server->soul)) != 0) { - fprintf(stderr, "Failed to hot reload soul"); + if ((ec = world_hot_reload_same_state(&server->world)) != 0) { + fprintf(stderr, "Failed to hot reload world"); exit(1); } } } else { - /* Pass the information along to the soul for the soul to handle. The - * soul will return via 'handled' whether or not the key event was handled + /* Pass the information along to the world for the world to handle. The + * world will return via 'handled' whether or not the key event was handled * or not. */ if (nsyms > 0) { codepoint = xkb_state_key_get_utf32(keyboard->wlr_keyboard->xkb_state, keycode); - soul_call_update_state(server->soul, arksoul_export_handle_keybinding, - keyboard->wlr_keyboard, event, modifiers, syms[0], - codepoint, &handled); + world_call_update_state(server->world, arkworld_export_handle_keybinding, + keyboard->wlr_keyboard, event, modifiers, syms[0], + codepoint, &handled); } } } @@ -440,9 +565,8 @@ static void server_cursor_motion(struct wl_listener *listener, void *data) wlr_cursor_move(server->cursor, &event->pointer->base, event->delta_x, event->delta_y); process_cursor_motion(server, event->time_msec); - soul_call_update_state(server->soul, arksoul_export_handle_motion, event, - modifiers, - 0, server->cursor->x, server->cursor->y); + world_call_update_state(server->world, arkworld_export_handle_motion, event, + modifiers, 0, server->cursor->x, server->cursor->y); } static void server_cursor_motion_absolute(struct wl_listener *listener, @@ -465,9 +589,8 @@ static void server_cursor_motion_absolute(struct wl_listener *listener, wlr_cursor_warp_absolute(server->cursor, &event->pointer->base, event->x, event->y); process_cursor_motion(server, event->time_msec); - soul_call_update_state(server->soul, arksoul_export_handle_motion, event, - modifiers, - 1, server->cursor->x, server->cursor->y); + world_call_update_state(server->world, arkworld_export_handle_motion, event, + modifiers, 1, server->cursor->x, server->cursor->y); } static void server_cursor_button(struct wl_listener *listener, void *data) @@ -481,8 +604,8 @@ static void server_cursor_button(struct wl_listener *listener, void *data) struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat); uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard); - soul_call_update_state(server->soul, arksoul_export_handle_button, event, - modifiers); + world_call_update_state(server->world, arkworld_export_handle_button, event, + modifiers); /* Notify the client with pointer focus that a button press has occurred */ // wlr_seat_pointer_notify_button(server->seat, event->time_msec, @@ -553,12 +676,18 @@ static void output_request_state(struct wl_listener *listener, void *data) wl_container_of(listener, output, request_state); const struct wlr_output_event_request_state *event = data; wlr_output_commit_state(output->wlr_output, event->state); + output_update_background(output); } static void output_destroy(struct wl_listener *listener, void *data) { struct montis_output *output = wl_container_of(listener, output, destroy); + if (output->background) { + wlr_scene_node_destroy(&output->background->node); + output->background = NULL; + } + wl_list_remove(&output->frame.link); wl_list_remove(&output->request_state.link); wl_list_remove(&output->destroy.link); @@ -630,6 +759,8 @@ static void server_new_output(struct wl_listener *listener, void *data) wlr_scene_output_create(server->scene, wlr_output); wlr_scene_output_layout_add_output(server->scene_layout, l_output, scene_output); + + output_update_background(output); } static void xdg_toplevel_map(struct wl_listener *listener, void *data) @@ -640,9 +771,9 @@ static void xdg_toplevel_map(struct wl_listener *listener, void *data) wl_list_insert(&toplevel->server->toplevels, &toplevel->link); fprintf(stderr, "Surface map ...\n"); - soul_call_update_state(toplevel->server->soul, arksoul_export_handle_surface, - toplevel, - SURFACE_MAP); + world_call_update_state(toplevel->server->world, + arkworld_export_handle_surface, toplevel, + SURFACE_MAP); fprintf(stderr, "/ Surface map ...\n"); focus_toplevel(toplevel, toplevel->xdg_toplevel->base->surface); @@ -659,9 +790,9 @@ static void xdg_toplevel_unmap(struct wl_listener *listener, void *data) } fprintf(stderr, "Surface unmap ...\n"); - soul_call_update_state(toplevel->server->soul, arksoul_export_handle_surface, - toplevel, - SURFACE_UNMAP); + world_call_update_state(toplevel->server->world, + arkworld_export_handle_surface, toplevel, + SURFACE_UNMAP); fprintf(stderr, "/ Surface map ...\n"); wl_list_remove(&toplevel->link); @@ -682,9 +813,9 @@ static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) wl_list_remove(&toplevel->request_fullscreen.link); fprintf(stderr, "Surface destroy ...\n"); - soul_call_update_state(toplevel->server->soul, arksoul_export_handle_surface, - toplevel, - SURFACE_DELETE); + world_call_update_state(toplevel->server->world, + arkworld_export_handle_surface, toplevel, + SURFACE_DELETE); fprintf(stderr, "/ Surface destroy ...\n"); free(toplevel); @@ -843,8 +974,7 @@ static void xdg_decoration_request_mode(struct wl_listener *listener, static void xdg_decoration_destroy(struct wl_listener *listener, void *data) { - struct montis_xdg_decoration *dec = - wl_container_of(listener, dec, destroy); + struct montis_xdg_decoration *dec = wl_container_of(listener, dec, destroy); wl_list_remove(&dec->request_mode.link); wl_list_remove(&dec->destroy.link); free(dec); @@ -927,35 +1057,42 @@ int main(int argc, char *argv[]) { wlr_log_init(WLR_DEBUG, NULL); char *startup_cmd = NULL; - char *soul_path = NULL; + char *world_path = NULL; + char *background_path = NULL; int c; - while ((c = getopt(argc, argv, "s:p:h")) != -1) { + while ((c = getopt(argc, argv, "s:p:b:h")) != -1) { switch (c) { case 's': startup_cmd = optarg; break; case 'p': - soul_path = optarg; + world_path = optarg; + break; + case 'b': + background_path = optarg; break; default: - printf("Usage: %s -p [soul] [-s startup command]\n", argv[0]); + printf("Usage: %s -p [world] [-s startup command] [-b background.png]\n", + argv[0]); return 0; } } - if (optind < argc || !soul_path) { - printf("Usage: %s -p [soul] [-s startup command]\n", argv[0]); + if (optind < argc || !world_path) { + printf("Usage: %s -p [world] [-s startup command] [-b background.png]\n", + argv[0]); return 0; } struct montis_server server = {0}; + server.background_path = background_path; - if (load_soul_from_file(argc, argv, soul_path, &server.soul)) { - fprintf(stderr, "Failed to read soul from file.\n"); + if (load_world_from_file(argc, argv, world_path, &server.world)) { + fprintf(stderr, "Failed to read world from file.\n"); return 1; } - soul_cold_start(&server.soul); + world_cold_start(&server.world); /* The Wayland display is managed by libwayland. It handles accepting * clients from the Unix socket, manging Wayland globals, and so on. */ @@ -1024,6 +1161,13 @@ int main(int argc, char *argv[]) server.scene_layout = wlr_scene_attach_output_layout(server.scene, server.output_layout); + if (server.background_path) { + server.background_buffer = load_background_buffer(server.background_path); + if (!server.background_buffer) { + wlr_log(WLR_ERROR, "background image disabled"); + } + } + /* Set up xdg-shell version 3. The xdg-shell is a Wayland protocol which is * used for application windows. For more detail on shells, refer to * https://drewdevault.com/2018/07/29/Wayland-shells.html. @@ -1133,6 +1277,10 @@ int main(int argc, char *argv[]) * server. */ wl_display_destroy_clients(server.wl_display); wlr_scene_node_destroy(&server.scene->tree.node); + if (server.background_buffer) { + wlr_buffer_drop(server.background_buffer); + server.background_buffer = NULL; + } wlr_xcursor_manager_destroy(server.cursor_mgr); wlr_output_layout_destroy(server.output_layout); wl_display_destroy(server.wl_display); diff --git a/ark/src/world.c b/ark/src/world.c new file mode 100644 index 0000000..e7641ed --- /dev/null +++ b/ark/src/world.c @@ -0,0 +1,199 @@ +#include "world.h" + +#include <ctype.h> +#include <dlfcn.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> + +/* Utility function for showing the marshalled states as hex code */ +static void shx(uint8_t *state, uint32_t sz) +{ + uint32_t i = 0; + while (i < sz) { + for (int j = 0; j < 16; ++j) { + if (i < sz) { + printf("%02x ", (unsigned int)state[i]); + } + else { + printf(" "); + } + ++i; + } + + i -= 16; + + printf(" "); + + for (int j = 0; j < 16; ++j) { + if (i < sz) { + if (isprint(state[i]) && !isspace(state[i])) { + printf("%c", state[i]); + } + else { + printf("."); + } + } + else { + printf(" "); + } + ++i; + } + printf("\n"); + } +} + +int load_world_from_dl_(dlhandle_t dl, world_t *world); + +static void lock(world_t *world) { pthread_mutex_lock(&world->lock); }; + +static void unlock(world_t *world) { pthread_mutex_unlock(&world->lock); }; + +static int load_world_from_file_(int argc, char **argv, const char *filename, + world_t *world) +{ + dlhandle_t lib = dlopen(filename, RTLD_NOW | RTLD_GLOBAL); + int ec = 0; + + if (!lib) { + fprintf(stderr, "Failed to open library: %s: %s\n", filename, dlerror()); + ec = 1; + goto end; + } + + printf("Loading file.\n"); + ec = load_world_from_dl_(lib, world); + + if (ec) { + goto end; + } + + strncpy(world->filename, filename, sizeof(world->filename)); + world->argc = argc; + world->argv = argv; + + world->arkworld_export_load(world->argc, world->argv); +end: + return ec; +} + +static void maybe_run_metaload(int argc, char **argv, world_t *world) +{ + static char *loaded_worlds[12]; + int i; + for (i = 0; i < 12 && loaded_worlds[i]; ++i) { + if (strcmp(loaded_worlds[i], world->world_name) == 0) { + return; // World is already loaded + } + } + loaded_worlds[i] = strdup(world->world_name); + + printf("First time loading %s, running metaload.\n", world->world_name); + if (world->arkworld_export_metaload) { + world->arkworld_export_metaload(argc, argv); + } +} + +int load_world_from_file(int argc, char **argv, const char *filename, + world_t *world) +{ + memset(world, 0, sizeof(*world)); + + pthread_mutexattr_t attr; + if (pthread_mutexattr_init(&attr)) { + perror("pthread_mutexattr_init"); + return 1; + } + + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) { + perror("pthread_mutexattr_settype"); + return 1; + } + + if (pthread_mutex_init(&world->lock, &attr)) { + pthread_mutexattr_destroy(&attr); + perror("pthread_mutexattr_init"); + return 1; + } + pthread_mutexattr_destroy(&attr); + int rc = load_world_from_file_(argc, argv, filename, world); + + if (rc == 0) { + maybe_run_metaload(argc, argv, world); + } + + return rc; +} + +int world_hot_reload_same_state(world_t *world) +{ + char filename_cpy[PATH_MAX]; + strncpy(filename_cpy, world->filename, sizeof(filename_cpy)); + return world_hot_reload(world->argc, world->argv, filename_cpy, world); +} + +int world_hot_reload(int argc, char **argv, const char *filepath, + world_t *world) +{ + int ec = 0; + uint32_t sz = 0; + uint8_t *marshalled_state = NULL; + + printf("Hot Reloading %s\n", world->world_name); + lock(world); + + printf("Marshalling state ...\n"); + marshalled_state = world->arkworld_export_preserve(world->state, &sz); + + printf("Calling teardown ...\n"); + world->arkworld_export_release(world->state); + + printf("State Marshalled:\n"); + shx(marshalled_state, sz); + + printf("Unloading old library handle.\n"); + if (dlclose(world->library_handle)) { + printf("Could not close library handle: %s\n", dlerror()); + } + + if ((ec = load_world_from_file_(argc, argv, filepath, world))) { + goto fail; + } + + printf("Hot starting world ...\n"); + world->state = world->arkworld_export_rebirth(world, marshalled_state, sz); + +fail: + free(marshalled_state); + unlock(world); + return ec; +} + +void world_run_requested_actions(world_t *world) +{ + lock(world); + requested_action_t requested_actions[MAX_QUEUED_ACTIONS]; + size_t n_requested_actions = world->n_requested_actions; + memcpy(&requested_actions, world->requested_actions, + sizeof(requested_actions)); + world->n_requested_actions = 0; + unlock(world); + + size_t i; + for (i = 0; i < n_requested_actions; ++i) { + requested_actions[i].action(world, requested_actions[i].str_arg); + if (requested_actions[i].arg_dtor) { + requested_actions[i].arg_dtor(requested_actions[i].ptr_arg); + } + } +} + +void world_cold_start(world_t *world) +{ + lock(world); + world->state = world->arkworld_export_enworld(world); + unlock(world); +} diff --git a/ark/src/soul_load.c b/ark/src/world_load.c index fcf04a9..098c4b0 100644 --- a/ark/src/soul_load.c +++ b/ark/src/world_load.c @@ -1,37 +1,37 @@ -#include "soul.h" +#include "world.h" #include <dlfcn.h> #include <stdio.h> -#include "soul_exports.h" +#include "world_exports.h" -int load_soul_from_dl_(dlhandle_t dl, soul_t *soul) +int load_world_from_dl_(dlhandle_t dl, world_t *world) { void *ptr; int ret = 0; - const char **name = dlsym(dl, "soul_name"); + const char **name = dlsym(dl, "world_name"); if (name) { - soul->soul_name = *name; + world->world_name = *name; } else { - soul->soul_name = NULL; + world->world_name = NULL; } - soul->state = NULL; - soul->library_handle = dl; + world->state = NULL; + world->library_handle = dl; #define LOAD_SYM(ret_type, sym, args) \ do { \ ptr = dlsym(dl, #sym); \ if (!ptr) { \ - fprintf(stderr, "Soul missing %s\n", #sym); \ + fprintf(stderr, "World missing %s\n", #sym); \ ret |= 1; \ } \ - soul->sym = (ret_type(*) args)ptr; \ + world->sym = (ret_type(*) args)ptr; \ } while (0); - ARKSOUL_EXPORTS(LOAD_SYM); + ARKWORLD_EXPORTS(LOAD_SYM); #undef LOAD_SYM |