factor out sdl input
Some checks failed
Build and Deploy / build-macos (push) Failing after 2s
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
Build and Deploy / build-linux (push) Has been cancelled
Some checks failed
Build and Deploy / build-macos (push) Failing after 2s
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
Build and Deploy / build-linux (push) Has been cancelled
This commit is contained in:
@@ -286,7 +286,7 @@ sources = []
|
||||
src += [
|
||||
'anim.c', 'config.c', 'datastream.c','font.c','HandmadeMath.c','jsffi.c','model.c',
|
||||
'render.c','simplex.c','spline.c', 'transform.c','cell.c', 'wildmatch.c',
|
||||
'sprite.c', 'rtree.c', 'qjs_nota.c', 'qjs_soloud.c', 'qjs_sdl.c', 'qjs_sdl_video.c', 'qjs_sdl_surface.c', 'qjs_math.c', 'qjs_geometry.c', 'qjs_transform.c', 'qjs_sprite.c', 'qjs_io.c', 'qjs_fd.c', 'qjs_os.c', 'qjs_actor.c',
|
||||
'sprite.c', 'rtree.c', 'qjs_nota.c', 'qjs_soloud.c', 'qjs_sdl.c', 'qjs_sdl_input.c', 'qjs_sdl_video.c', 'qjs_sdl_surface.c', 'qjs_math.c', 'qjs_geometry.c', 'qjs_transform.c', 'qjs_sprite.c', 'qjs_io.c', 'qjs_fd.c', 'qjs_os.c', 'qjs_actor.c',
|
||||
'qjs_qr.c', 'qjs_wota.c', 'monocypher.c', 'qjs_blob.c', 'qjs_crypto.c', 'qjs_time.c', 'qjs_http.c', 'qjs_rtree.c', 'qjs_spline.c', 'qjs_js.c', 'qjs_debug.c', 'picohttpparser.c', 'qjs_miniz.c'
|
||||
]
|
||||
# quirc src
|
||||
|
||||
786
source/cell.c
786
source/cell.c
@@ -53,12 +53,6 @@ static unsigned char *zip_buffer_global = NULL;
|
||||
static char *prosperon = NULL;
|
||||
cell_rt *root_cell = NULL;
|
||||
|
||||
/* Event watch subscribers */
|
||||
char **event_watchers = NULL;
|
||||
SDL_Mutex *event_watchers_mutex = NULL;
|
||||
|
||||
static Uint32 queue_event;
|
||||
|
||||
static SDL_AtomicInt engine_shutdown;
|
||||
static SDL_Thread **runners = NULL;
|
||||
|
||||
@@ -73,6 +67,7 @@ static inline uint64_t now_ns()
|
||||
return SDL_GetTicksNS();
|
||||
}
|
||||
|
||||
// Add a message into each actor's event queue for expired timers
|
||||
static void process_due_timers(void)
|
||||
{
|
||||
uint64_t tnow = now_ns();
|
||||
@@ -203,7 +198,7 @@ void actor_free(cell_rt *actor)
|
||||
// Do not go forward with actor destruction until the actor is completely free
|
||||
SDL_LockMutex(actor->mutex);
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
SDL_LockMutex(actor->turn);
|
||||
SDL_LockMutex(actor->mutex);
|
||||
|
||||
JSContext *js = actor->context;
|
||||
|
||||
@@ -256,8 +251,8 @@ void actor_free(cell_rt *actor)
|
||||
SDL_DestroyMutex(actor->mutex);
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
SDL_DestroyMutex(actor->msg_mutex);
|
||||
SDL_UnlockMutex(actor->turn);
|
||||
SDL_DestroyMutex(actor->turn);
|
||||
SDL_UnlockMutex(actor->mutex);
|
||||
SDL_DestroyMutex(actor->mutex);
|
||||
|
||||
free(actor);
|
||||
|
||||
@@ -266,11 +261,13 @@ void actor_free(cell_rt *actor)
|
||||
// exit_handler();
|
||||
}
|
||||
|
||||
static Uint32 actor_remove_cb(cell_rt *actor, Uint32 id, Uint32 interval)
|
||||
JSValue js_actor_remove_cb(JSContext *js, JSValue this_val, int argc, JSValue *argv)
|
||||
{
|
||||
cell_rt *actor = JS_GetContextOpaque(js);
|
||||
|
||||
if (actor->need_stop) {
|
||||
actor_free(actor);
|
||||
return 0;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
if (JS_IsUndefined(actor->unneeded))
|
||||
@@ -282,7 +279,7 @@ static Uint32 actor_remove_cb(cell_rt *actor, Uint32 id, Uint32 interval)
|
||||
SDL_UnlockMutex(actor->mutex);
|
||||
actor_free(actor);
|
||||
}
|
||||
return 0;
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
void js_dofree(JSRuntime *rt, void *opaque, void *ptr)
|
||||
@@ -446,7 +443,6 @@ cell_rt *create_actor(void *wota)
|
||||
|
||||
actor->mutex = SDL_CreateMutex(); /* Protects JSContext + state */
|
||||
actor->msg_mutex = SDL_CreateMutex(); /* Mailbox queue lock */
|
||||
actor->turn = SDL_CreateMutex();
|
||||
|
||||
/* Lock actor->mutex while initializing JS runtime. */
|
||||
SDL_LockMutex(actor->mutex);
|
||||
@@ -511,13 +507,19 @@ const char *send_message(const char *id, void *msg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set_actor_state should check if any letters are pending. */
|
||||
/*
|
||||
set_actor_state should check if any letters are pending.
|
||||
|
||||
*/
|
||||
void set_actor_state(cell_rt *actor)
|
||||
{
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
if (actor->need_stop) {
|
||||
if (!actor->ar)
|
||||
actor->ar = SDL_AddTimerNS(0, actor_remove_cb, actor);
|
||||
if (!actor->ar) {
|
||||
JSValue remove_cb = JS_NewCFunction(actor->context, js_actor_remove_cb, "actor_remove", 0);
|
||||
actor->ar = scheduler_add_timer(actor, 0, remove_cb);
|
||||
JS_FreeValue(actor->context, remove_cb);
|
||||
}
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
return;
|
||||
}
|
||||
@@ -535,9 +537,6 @@ void set_actor_state(cell_rt *actor)
|
||||
SDL_LockMutex(queue_mutex);
|
||||
if (actor->main_thread_only) {
|
||||
arrput(main_ready_queue, actor);
|
||||
SDL_Event event;
|
||||
event.type = queue_event;
|
||||
SDL_PushEvent(&event);
|
||||
} else {
|
||||
SDL_SignalCondition(queue_cond);
|
||||
arrput(ready_queue, actor);
|
||||
@@ -556,15 +555,17 @@ void set_actor_state(cell_rt *actor)
|
||||
}
|
||||
|
||||
END:
|
||||
if (actor->state == ACTOR_IDLE && !actor->ar && !has_upcoming)
|
||||
actor->ar = SDL_AddTimerNS(SDL_SECONDS_TO_NS(actor->ar_secs), actor_remove_cb, actor);
|
||||
if (actor->state == ACTOR_IDLE && !actor->ar && !has_upcoming) {
|
||||
JSValue remove_cb = JS_NewCFunction(actor->context, js_actor_remove_cb, "actor_remove", 0);
|
||||
actor->ar = scheduler_add_timer(actor, actor->ar_secs, remove_cb);
|
||||
JS_FreeValue(actor->context, remove_cb);
|
||||
}
|
||||
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
}
|
||||
|
||||
void actor_turn(cell_rt *actor, int greedy)
|
||||
void actor_turn(cell_rt *actor)
|
||||
{
|
||||
SDL_LockMutex(actor->turn);
|
||||
#ifdef TRACY_ENABLE
|
||||
if (tracy_profiling_enabled)
|
||||
TracyCFiberEnter(actor->name);
|
||||
@@ -573,19 +574,8 @@ void actor_turn(cell_rt *actor, int greedy)
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
actor->state = ACTOR_RUNNING;
|
||||
|
||||
int letters_count = 0;
|
||||
int need_stop = 0;
|
||||
JSValue result;
|
||||
|
||||
letters_count = arrlen(actor->letters);
|
||||
need_stop = actor->need_stop;
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
|
||||
if (need_stop) goto KILL;
|
||||
if (!letters_count) goto END;
|
||||
|
||||
PROCESS_LETTER:
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
letter l = actor->letters[0];
|
||||
arrdel(actor->letters, 0);
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
@@ -606,41 +596,12 @@ void actor_turn(cell_rt *actor, int greedy)
|
||||
|
||||
SDL_UnlockMutex(actor->mutex);
|
||||
|
||||
if (!greedy) goto END;
|
||||
|
||||
SDL_LockMutex(actor->msg_mutex);
|
||||
need_stop = actor->need_stop;
|
||||
letters_count = arrlen(actor->letters);
|
||||
SDL_UnlockMutex(actor->msg_mutex);
|
||||
|
||||
if (need_stop) goto KILL;
|
||||
if (!letters_count) goto END;
|
||||
|
||||
SDL_LockMutex(queue_mutex);
|
||||
int queuen = arrlen(ready_queue);
|
||||
SDL_UnlockMutex(queue_mutex);
|
||||
|
||||
if (queuen != 0)
|
||||
goto END;
|
||||
|
||||
goto PROCESS_LETTER;
|
||||
|
||||
END:
|
||||
#ifdef TRACY_ENABLE
|
||||
if (tracy_profiling_enabled)
|
||||
TracyCFiberLeave(actor->name);
|
||||
#endif
|
||||
SDL_UnlockMutex(actor->turn);
|
||||
|
||||
set_actor_state(actor);
|
||||
return;
|
||||
|
||||
KILL:
|
||||
#ifdef TRACY_ENABLE
|
||||
if (tracy_profiling_enabled)
|
||||
TracyCFiberLeave(actor->name);
|
||||
#endif
|
||||
SDL_UnlockMutex(actor->turn);
|
||||
actor_free(actor);
|
||||
}
|
||||
|
||||
|
||||
@@ -866,7 +827,7 @@ static int crank_actor(void *data)
|
||||
}
|
||||
SDL_UnlockMutex(queue_mutex);
|
||||
|
||||
if (actor) actor_turn(actor, 1);
|
||||
if (actor) actor_turn(actor);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -887,661 +848,6 @@ static void signal_handler(int sig)
|
||||
exit_handler();
|
||||
}
|
||||
|
||||
// Assume these helper functions exist or need to be implemented
|
||||
const char* event_type_to_string(Uint32 event_type) {
|
||||
switch (event_type) {
|
||||
// Application events
|
||||
case SDL_EVENT_QUIT: return "quit";
|
||||
case SDL_EVENT_TERMINATING: return "terminating";
|
||||
case SDL_EVENT_LOW_MEMORY: return "low_memory";
|
||||
case SDL_EVENT_WILL_ENTER_BACKGROUND: return "will_enter_background";
|
||||
case SDL_EVENT_DID_ENTER_BACKGROUND: return "did_enter_background";
|
||||
case SDL_EVENT_WILL_ENTER_FOREGROUND: return "will_enter_foreground";
|
||||
case SDL_EVENT_DID_ENTER_FOREGROUND: return "did_enter_foreground";
|
||||
case SDL_EVENT_LOCALE_CHANGED: return "locale_changed";
|
||||
case SDL_EVENT_SYSTEM_THEME_CHANGED: return "system_theme_changed";
|
||||
|
||||
// Display events
|
||||
case SDL_EVENT_DISPLAY_ORIENTATION: return "display_orientation";
|
||||
case SDL_EVENT_DISPLAY_ADDED: return "display_added";
|
||||
case SDL_EVENT_DISPLAY_REMOVED: return "display_removed";
|
||||
case SDL_EVENT_DISPLAY_MOVED: return "display_moved";
|
||||
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED: return "display_desktop_mode_changed";
|
||||
case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED: return "display_current_mode_changed";
|
||||
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED: return "display_content_scale_changed";
|
||||
|
||||
// Window events
|
||||
case SDL_EVENT_WINDOW_SHOWN: return "window_shown";
|
||||
case SDL_EVENT_WINDOW_HIDDEN: return "window_hidden";
|
||||
case SDL_EVENT_WINDOW_EXPOSED: return "window_exposed";
|
||||
case SDL_EVENT_WINDOW_MOVED: return "window_moved";
|
||||
case SDL_EVENT_WINDOW_RESIZED: return "window_resized";
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: return "window_pixel_size_changed";
|
||||
case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED: return "window_metal_view_resized";
|
||||
case SDL_EVENT_WINDOW_MINIMIZED: return "window_minimized";
|
||||
case SDL_EVENT_WINDOW_MAXIMIZED: return "window_maximized";
|
||||
case SDL_EVENT_WINDOW_RESTORED: return "window_restored";
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER: return "window_mouse_enter";
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE: return "window_mouse_leave";
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED: return "window_focus_gained";
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST: return "window_focus_lost";
|
||||
case SDL_EVENT_WINDOW_CLOSE_REQUESTED: return "window_close_requested";
|
||||
case SDL_EVENT_WINDOW_HIT_TEST: return "window_hit_test";
|
||||
case SDL_EVENT_WINDOW_ICCPROF_CHANGED: return "window_iccprof_changed";
|
||||
case SDL_EVENT_WINDOW_DISPLAY_CHANGED: return "window_display_changed";
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: return "window_display_scale_changed";
|
||||
case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED: return "window_safe_area_changed";
|
||||
case SDL_EVENT_WINDOW_OCCLUDED: return "window_occluded";
|
||||
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN: return "window_enter_fullscreen";
|
||||
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN: return "window_leave_fullscreen";
|
||||
case SDL_EVENT_WINDOW_DESTROYED: return "window_destroyed";
|
||||
case SDL_EVENT_WINDOW_HDR_STATE_CHANGED: return "window_hdr_state_changed";
|
||||
|
||||
// Keyboard events
|
||||
case SDL_EVENT_KEY_DOWN: return "key_down";
|
||||
case SDL_EVENT_KEY_UP: return "key_up";
|
||||
case SDL_EVENT_TEXT_EDITING: return "text_editing";
|
||||
case SDL_EVENT_TEXT_INPUT: return "text_input";
|
||||
case SDL_EVENT_KEYMAP_CHANGED: return "keymap_changed";
|
||||
case SDL_EVENT_KEYBOARD_ADDED: return "keyboard_added";
|
||||
case SDL_EVENT_KEYBOARD_REMOVED: return "keyboard_removed";
|
||||
case SDL_EVENT_TEXT_EDITING_CANDIDATES: return "text_editing_candidates";
|
||||
|
||||
// Mouse events
|
||||
case SDL_EVENT_MOUSE_MOTION: return "mouse_motion";
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN: return "mouse_button_down";
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP: return "mouse_button_up";
|
||||
case SDL_EVENT_MOUSE_WHEEL: return "mouse_wheel";
|
||||
case SDL_EVENT_MOUSE_ADDED: return "mouse_added";
|
||||
case SDL_EVENT_MOUSE_REMOVED: return "mouse_removed";
|
||||
|
||||
// Joystick events
|
||||
case SDL_EVENT_JOYSTICK_AXIS_MOTION: return "joystick_axis_motion";
|
||||
case SDL_EVENT_JOYSTICK_BALL_MOTION: return "joystick_ball_motion";
|
||||
case SDL_EVENT_JOYSTICK_HAT_MOTION: return "joystick_hat_motion";
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_DOWN: return "joystick_button_down";
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_UP: return "joystick_button_up";
|
||||
case SDL_EVENT_JOYSTICK_ADDED: return "joystick_added";
|
||||
case SDL_EVENT_JOYSTICK_REMOVED: return "joystick_removed";
|
||||
case SDL_EVENT_JOYSTICK_BATTERY_UPDATED: return "joystick_battery_updated";
|
||||
case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE: return "joystick_update_complete";
|
||||
|
||||
// Gamepad events
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION: return "gamepad_axis_motion";
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN: return "gamepad_button_down";
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP: return "gamepad_button_up";
|
||||
case SDL_EVENT_GAMEPAD_ADDED: return "gamepad_added";
|
||||
case SDL_EVENT_GAMEPAD_REMOVED: return "gamepad_removed";
|
||||
case SDL_EVENT_GAMEPAD_REMAPPED: return "gamepad_remapped";
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN: return "gamepad_touchpad_down";
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION: return "gamepad_touchpad_motion";
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP: return "gamepad_touchpad_up";
|
||||
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: return "gamepad_sensor_update";
|
||||
case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE: return "gamepad_update_complete";
|
||||
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED: return "gamepad_steam_handle_updated";
|
||||
|
||||
// Touch events
|
||||
case SDL_EVENT_FINGER_DOWN: return "finger_down";
|
||||
case SDL_EVENT_FINGER_UP: return "finger_up";
|
||||
case SDL_EVENT_FINGER_MOTION: return "finger_motion";
|
||||
|
||||
// Clipboard events
|
||||
case SDL_EVENT_CLIPBOARD_UPDATE: return "clipboard_update";
|
||||
|
||||
// Drag and drop events
|
||||
case SDL_EVENT_DROP_FILE: return "drop_file";
|
||||
case SDL_EVENT_DROP_TEXT: return "drop_text";
|
||||
case SDL_EVENT_DROP_BEGIN: return "drop_begin";
|
||||
case SDL_EVENT_DROP_COMPLETE: return "drop_complete";
|
||||
case SDL_EVENT_DROP_POSITION: return "drop_position";
|
||||
|
||||
// Audio device events
|
||||
case SDL_EVENT_AUDIO_DEVICE_ADDED: return "audio_device_added";
|
||||
case SDL_EVENT_AUDIO_DEVICE_REMOVED: return "audio_device_removed";
|
||||
case SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED: return "audio_device_format_changed";
|
||||
|
||||
// Sensor events
|
||||
case SDL_EVENT_SENSOR_UPDATE: return "sensor_update";
|
||||
|
||||
// Pen events
|
||||
case SDL_EVENT_PEN_PROXIMITY_IN: return "pen_proximity_in";
|
||||
case SDL_EVENT_PEN_PROXIMITY_OUT: return "pen_proximity_out";
|
||||
case SDL_EVENT_PEN_DOWN: return "pen_down";
|
||||
case SDL_EVENT_PEN_UP: return "pen_up";
|
||||
case SDL_EVENT_PEN_BUTTON_DOWN: return "pen_button_down";
|
||||
case SDL_EVENT_PEN_BUTTON_UP: return "pen_button_up";
|
||||
case SDL_EVENT_PEN_MOTION: return "pen_motion";
|
||||
case SDL_EVENT_PEN_AXIS: return "pen_axis";
|
||||
|
||||
// Camera events
|
||||
case SDL_EVENT_CAMERA_DEVICE_ADDED: return "camera_device_added";
|
||||
case SDL_EVENT_CAMERA_DEVICE_REMOVED: return "camera_device_removed";
|
||||
case SDL_EVENT_CAMERA_DEVICE_APPROVED: return "camera_device_approved";
|
||||
case SDL_EVENT_CAMERA_DEVICE_DENIED: return "camera_device_denied";
|
||||
|
||||
// Render events
|
||||
case SDL_EVENT_RENDER_TARGETS_RESET: return "render_targets_reset";
|
||||
case SDL_EVENT_RENDER_DEVICE_RESET: return "render_device_reset";
|
||||
case SDL_EVENT_RENDER_DEVICE_LOST: return "render_device_lost";
|
||||
|
||||
// User event (assuming it should be included)
|
||||
case SDL_EVENT_USER: return "user";
|
||||
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char* mouse_button_to_string(int mouse) {
|
||||
switch (mouse) {
|
||||
case SDL_BUTTON_LEFT: return "left";
|
||||
case SDL_BUTTON_MIDDLE: return "middle";
|
||||
case SDL_BUTTON_RIGHT: return "right";
|
||||
case SDL_BUTTON_X1: return "x1";
|
||||
case SDL_BUTTON_X2: return "x2";
|
||||
default: return "left";
|
||||
}
|
||||
}
|
||||
|
||||
static void wota_write_vec2(WotaBuffer *wb, double x, double y) {
|
||||
// We'll store as WOTA_ARR of length 2, then two numbers
|
||||
wota_write_array(wb, 2);
|
||||
wota_write_number(wb, x);
|
||||
wota_write_number(wb, y);
|
||||
}
|
||||
|
||||
static int event2wota_count_props(const SDL_Event *event)
|
||||
{
|
||||
// We always store at least "type" and "timestamp".
|
||||
int count = 2;
|
||||
|
||||
switch (event->type) {
|
||||
|
||||
case SDL_EVENT_AUDIO_DEVICE_ADDED:
|
||||
case SDL_EVENT_AUDIO_DEVICE_REMOVED:
|
||||
count += 2; // which, recording
|
||||
break;
|
||||
|
||||
case SDL_EVENT_DISPLAY_ORIENTATION:
|
||||
case SDL_EVENT_DISPLAY_ADDED:
|
||||
case SDL_EVENT_DISPLAY_REMOVED:
|
||||
case SDL_EVENT_DISPLAY_MOVED:
|
||||
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
|
||||
case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED:
|
||||
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:
|
||||
count += 3; // which, data1, data2
|
||||
break;
|
||||
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
count += 5;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
// window, which, scroll, mouse => 4 extra
|
||||
count += 4;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
// window, which, down, button, clicks, mouse => 6 extra
|
||||
count += 6;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_SENSOR_UPDATE:
|
||||
// which, sensor_timestamp => 2 extra
|
||||
count += 2;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
case SDL_EVENT_KEY_UP:
|
||||
// window, which, down, repeat, key, scancode, mod => 7 extra
|
||||
count += 7;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_FINGER_MOTION:
|
||||
case SDL_EVENT_FINGER_DOWN:
|
||||
case SDL_EVENT_FINGER_UP:
|
||||
// touch, finger, pos, d_pos, pressure, window => 6 extra
|
||||
count += 6;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_DROP_BEGIN:
|
||||
case SDL_EVENT_DROP_FILE:
|
||||
case SDL_EVENT_DROP_TEXT:
|
||||
case SDL_EVENT_DROP_COMPLETE:
|
||||
case SDL_EVENT_DROP_POSITION:
|
||||
// window, pos, data, source => 4 extra
|
||||
count += 4;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_TEXT_INPUT:
|
||||
// window, text, mod => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_CAMERA_DEVICE_APPROVED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_REMOVED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_ADDED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_DENIED:
|
||||
// which => 1 extra
|
||||
count += 1;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_CLIPBOARD_UPDATE:
|
||||
// owner => 1 extra
|
||||
count += 1;
|
||||
break;
|
||||
|
||||
/* Window events (just group them all together) */
|
||||
case SDL_EVENT_WINDOW_SHOWN:
|
||||
case SDL_EVENT_WINDOW_HIDDEN:
|
||||
case SDL_EVENT_WINDOW_EXPOSED:
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||
case SDL_EVENT_WINDOW_MAXIMIZED:
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
|
||||
case SDL_EVENT_WINDOW_HIT_TEST:
|
||||
case SDL_EVENT_WINDOW_ICCPROF_CHANGED:
|
||||
case SDL_EVENT_WINDOW_DISPLAY_CHANGED:
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
|
||||
case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED:
|
||||
case SDL_EVENT_WINDOW_OCCLUDED:
|
||||
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
|
||||
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
|
||||
case SDL_EVENT_WINDOW_DESTROYED:
|
||||
case SDL_EVENT_WINDOW_HDR_STATE_CHANGED:
|
||||
// which, data1, data2 => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_JOYSTICK_ADDED:
|
||||
case SDL_EVENT_JOYSTICK_REMOVED:
|
||||
case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE:
|
||||
// which => 1 extra
|
||||
count += 1;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
|
||||
// which, axis, value => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_JOYSTICK_BALL_MOTION:
|
||||
// which, ball, rel => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_UP:
|
||||
// which, button, down => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
case SDL_EVENT_GAMEPAD_REMAPPED:
|
||||
case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE:
|
||||
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED:
|
||||
// which => 1 extra
|
||||
count += 1;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
||||
// which, axis, value => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP:
|
||||
// which, button, down => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN:
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP:
|
||||
// which, touchpad, finger, pos, pressure => 5 extra
|
||||
count += 5;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE:
|
||||
// which, sensor, sensor_timestamp => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_USER:
|
||||
// cb => 1 extra
|
||||
count += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void event2wota_write(WotaBuffer *wb, const SDL_Event *e, int c) {
|
||||
wota_write_record(wb, (unsigned long long)c);
|
||||
wota_write_text(wb, "type");
|
||||
wota_write_text(wb, event_type_to_string(e->type));
|
||||
wota_write_text(wb, "timestamp");
|
||||
wota_write_number(wb, (double)e->common.timestamp);
|
||||
switch(e->type) {
|
||||
case SDL_EVENT_AUDIO_DEVICE_ADDED:
|
||||
case SDL_EVENT_AUDIO_DEVICE_REMOVED:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->adevice.which);
|
||||
wota_write_text(wb, "recording");
|
||||
wota_write_sym(wb, e->adevice.recording ? WOTA_TRUE : WOTA_FALSE);
|
||||
break;
|
||||
case SDL_EVENT_DISPLAY_ORIENTATION:
|
||||
case SDL_EVENT_DISPLAY_ADDED:
|
||||
case SDL_EVENT_DISPLAY_REMOVED:
|
||||
case SDL_EVENT_DISPLAY_MOVED:
|
||||
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
|
||||
case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED:
|
||||
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->display.displayID);
|
||||
wota_write_text(wb, "data1");
|
||||
wota_write_number(wb, (double)e->display.data1);
|
||||
wota_write_text(wb, "data2");
|
||||
wota_write_number(wb, (double)e->display.data2);
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->motion.windowID);
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->motion.which);
|
||||
wota_write_text(wb, "state");
|
||||
wota_write_number(wb, (double)e->motion.state);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->motion.x, (double)e->motion.y);
|
||||
wota_write_text(wb, "d_pos");
|
||||
wota_write_vec2(wb, (double)e->motion.xrel, (double)e->motion.yrel);
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->wheel.windowID);
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->wheel.which);
|
||||
wota_write_text(wb, "scroll");
|
||||
wota_write_vec2(wb, (double)e->wheel.x, (double)e->wheel.y);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->wheel.mouse_x, (double)e->wheel.mouse_y);
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->button.windowID);
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->button.which);
|
||||
wota_write_text(wb, "down");
|
||||
wota_write_sym(wb, e->button.down ? WOTA_TRUE : WOTA_FALSE);
|
||||
wota_write_text(wb, "button");
|
||||
wota_write_text(wb, mouse_button_to_string(e->button.button));
|
||||
wota_write_text(wb, "clicks");
|
||||
wota_write_number(wb, (double)e->button.clicks);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->button.x, (double)e->button.y);
|
||||
break;
|
||||
case SDL_EVENT_SENSOR_UPDATE:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->sensor.which);
|
||||
wota_write_text(wb, "sensor_timestamp");
|
||||
wota_write_number(wb, (double)e->sensor.sensor_timestamp);
|
||||
break;
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
case SDL_EVENT_KEY_UP:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->key.windowID);
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->key.which);
|
||||
wota_write_text(wb, "down");
|
||||
wota_write_sym(wb, e->key.down ? WOTA_TRUE : WOTA_FALSE);
|
||||
wota_write_text(wb, "repeat");
|
||||
wota_write_sym(wb, e->key.repeat ? WOTA_TRUE : WOTA_FALSE);
|
||||
wota_write_text(wb, "key");
|
||||
wota_write_number(wb, (double)e->key.key);
|
||||
wota_write_text(wb, "scancode");
|
||||
wota_write_number(wb, (double)e->key.scancode);
|
||||
wota_write_text(wb, "mod");
|
||||
wota_write_number(wb, 0);
|
||||
break;
|
||||
case SDL_EVENT_FINGER_MOTION:
|
||||
case SDL_EVENT_FINGER_DOWN:
|
||||
case SDL_EVENT_FINGER_UP:
|
||||
wota_write_text(wb, "touch");
|
||||
wota_write_number(wb, (double)e->tfinger.touchID);
|
||||
wota_write_text(wb, "finger");
|
||||
wota_write_number(wb, (double)e->tfinger.fingerID);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->tfinger.x, (double)e->tfinger.y);
|
||||
wota_write_text(wb, "d_pos");
|
||||
wota_write_vec2(wb, (double)e->tfinger.dx, (double)e->tfinger.dy);
|
||||
wota_write_text(wb, "pressure");
|
||||
wota_write_number(wb, (double)e->tfinger.pressure);
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->key.windowID);
|
||||
break;
|
||||
case SDL_EVENT_DROP_BEGIN:
|
||||
case SDL_EVENT_DROP_FILE:
|
||||
case SDL_EVENT_DROP_TEXT:
|
||||
case SDL_EVENT_DROP_COMPLETE:
|
||||
case SDL_EVENT_DROP_POSITION:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->drop.windowID);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->drop.x, (double)e->drop.y);
|
||||
wota_write_text(wb, "data");
|
||||
wota_write_text(wb, e->drop.data ? e->drop.data : "");
|
||||
wota_write_text(wb, "source");
|
||||
wota_write_text(wb, e->drop.source ? e->drop.source : "");
|
||||
break;
|
||||
case SDL_EVENT_TEXT_INPUT:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->text.windowID);
|
||||
wota_write_text(wb, "text");
|
||||
wota_write_text(wb, e->text.text);
|
||||
wota_write_text(wb, "mod");
|
||||
wota_write_number(wb, 0);
|
||||
break;
|
||||
case SDL_EVENT_CAMERA_DEVICE_APPROVED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_REMOVED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_ADDED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_DENIED:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->cdevice.which);
|
||||
break;
|
||||
case SDL_EVENT_CLIPBOARD_UPDATE:
|
||||
wota_write_text(wb, "owner");
|
||||
wota_write_sym(wb, e->clipboard.owner ? WOTA_TRUE : WOTA_FALSE);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_SHOWN:
|
||||
case SDL_EVENT_WINDOW_HIDDEN:
|
||||
case SDL_EVENT_WINDOW_EXPOSED:
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||
case SDL_EVENT_WINDOW_MAXIMIZED:
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
|
||||
case SDL_EVENT_WINDOW_HIT_TEST:
|
||||
case SDL_EVENT_WINDOW_ICCPROF_CHANGED:
|
||||
case SDL_EVENT_WINDOW_DISPLAY_CHANGED:
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
|
||||
case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED:
|
||||
case SDL_EVENT_WINDOW_OCCLUDED:
|
||||
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
|
||||
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
|
||||
case SDL_EVENT_WINDOW_DESTROYED:
|
||||
case SDL_EVENT_WINDOW_HDR_STATE_CHANGED:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->window.windowID);
|
||||
wota_write_text(wb, "data1");
|
||||
wota_write_number(wb, (double)e->window.data1);
|
||||
wota_write_text(wb, "data2");
|
||||
wota_write_number(wb, (double)e->window.data2);
|
||||
break;
|
||||
case SDL_EVENT_JOYSTICK_ADDED:
|
||||
case SDL_EVENT_JOYSTICK_REMOVED:
|
||||
case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->jdevice.which);
|
||||
break;
|
||||
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->jaxis.which);
|
||||
wota_write_text(wb, "axis");
|
||||
wota_write_number(wb, (double)e->jaxis.axis);
|
||||
wota_write_text(wb, "value");
|
||||
wota_write_number(wb, (double)e->jaxis.value);
|
||||
break;
|
||||
case SDL_EVENT_JOYSTICK_BALL_MOTION:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->jball.which);
|
||||
wota_write_text(wb, "ball");
|
||||
wota_write_number(wb, (double)e->jball.ball);
|
||||
wota_write_text(wb, "rel");
|
||||
wota_write_vec2(wb, (double)e->jball.xrel, (double)e->jball.yrel);
|
||||
break;
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_UP:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->jbutton.which);
|
||||
wota_write_text(wb, "button");
|
||||
wota_write_number(wb, (double)e->jbutton.button);
|
||||
wota_write_text(wb, "down");
|
||||
wota_write_sym(wb, e->jbutton.down ? WOTA_TRUE : WOTA_FALSE);
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
case SDL_EVENT_GAMEPAD_REMAPPED:
|
||||
case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE:
|
||||
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->gdevice.which);
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->gaxis.which);
|
||||
wota_write_text(wb, "axis");
|
||||
wota_write_number(wb, (double)e->gaxis.axis);
|
||||
wota_write_text(wb, "value");
|
||||
wota_write_number(wb, (double)e->gaxis.value);
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->gbutton.which);
|
||||
wota_write_text(wb, "button");
|
||||
wota_write_number(wb, (double)e->gbutton.button);
|
||||
wota_write_text(wb, "down");
|
||||
wota_write_sym(wb, e->gbutton.down ? WOTA_TRUE : WOTA_FALSE);
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN:
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->gtouchpad.which);
|
||||
wota_write_text(wb, "touchpad");
|
||||
wota_write_number(wb, (double)e->gtouchpad.touchpad);
|
||||
wota_write_text(wb, "finger");
|
||||
wota_write_number(wb, (double)e->gtouchpad.finger);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->gtouchpad.x, (double)e->gtouchpad.y);
|
||||
wota_write_text(wb, "pressure");
|
||||
wota_write_number(wb, (double)e->gtouchpad.pressure);
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->gsensor.which);
|
||||
wota_write_text(wb, "sensor");
|
||||
wota_write_number(wb, (double)e->gsensor.sensor);
|
||||
wota_write_text(wb, "sensor_timestamp");
|
||||
wota_write_number(wb, (double)e->gsensor.sensor_timestamp);
|
||||
break;
|
||||
case SDL_EVENT_USER:
|
||||
wota_write_text(wb, "cb");
|
||||
wota_write_number(wb, (double)(uintptr_t)e->user.data1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static WotaBuffer event2wota(const SDL_Event *event) {
|
||||
WotaBuffer wb;
|
||||
wota_buffer_init(&wb, 8);
|
||||
int n = event2wota_count_props(event);
|
||||
event2wota_write(&wb, event, n);
|
||||
return wb;
|
||||
}
|
||||
|
||||
bool event_watch(void *data, SDL_Event *e)
|
||||
{
|
||||
if (e->type == queue_event) return true;
|
||||
|
||||
SDL_LockMutex(event_watchers_mutex);
|
||||
int n_watchers = arrlen(event_watchers);
|
||||
if (n_watchers == 0) {
|
||||
SDL_UnlockMutex(event_watchers_mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Create a copy of watcher IDs while holding the lock */
|
||||
char **watchers_copy = NULL;
|
||||
arrsetcap(watchers_copy, n_watchers);
|
||||
for (int i = 0; i < n_watchers; i++) {
|
||||
arrput(watchers_copy, strdup(event_watchers[i]));
|
||||
}
|
||||
SDL_UnlockMutex(event_watchers_mutex);
|
||||
|
||||
WotaBuffer wb = event2wota(e);
|
||||
|
||||
for (int i = 0; i < arrlen(watchers_copy); i++) {
|
||||
if (actor_exists(watchers_copy[i])) {
|
||||
const char *err = send_message(watchers_copy[i], wota_dup_data(&wb));
|
||||
if (err) {
|
||||
/* Remove dead actor from watchers */
|
||||
SDL_LockMutex(event_watchers_mutex);
|
||||
for (int j = 0; j < arrlen(event_watchers); j++) {
|
||||
if (strcmp(event_watchers[j], watchers_copy[i]) == 0) {
|
||||
free(event_watchers[j]);
|
||||
arrdel(event_watchers, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(event_watchers_mutex);
|
||||
}
|
||||
} else {
|
||||
/* Remove dead actor from watchers */
|
||||
SDL_LockMutex(event_watchers_mutex);
|
||||
for (int j = 0; j < arrlen(event_watchers); j++) {
|
||||
if (strcmp(event_watchers[j], watchers_copy[i]) == 0) {
|
||||
free(event_watchers[j]);
|
||||
arrdel(event_watchers, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(event_watchers_mutex);
|
||||
}
|
||||
free(watchers_copy[i]);
|
||||
}
|
||||
|
||||
arrfree(watchers_copy);
|
||||
wota_buffer_free(&wb);
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@@ -1557,7 +863,6 @@ int main(int argc, char **argv)
|
||||
printf("CRITICAL ERROR: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
queue_event = SDL_RegisterEvents(1);
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
tracy_profiling_enabled = profile_enabled;
|
||||
@@ -1620,7 +925,6 @@ int main(int argc, char **argv)
|
||||
queue_mutex = SDL_CreateMutex();
|
||||
queue_cond = SDL_CreateCondition();
|
||||
actors_mutex = SDL_CreateMutex();
|
||||
event_watchers_mutex = SDL_CreateMutex();
|
||||
timer_mutex = SDL_CreateMutex();
|
||||
|
||||
/* Create the initial actor from the command line */
|
||||
@@ -1654,30 +958,10 @@ int main(int argc, char **argv)
|
||||
atexit(exit_handler);
|
||||
|
||||
/* Main loop: pump ready actors */
|
||||
SDL_Event event;
|
||||
const uint64_t fallback_sleep = 1000000ULL; /* 1 ms */
|
||||
|
||||
while (!SDL_GetAtomicInt(&engine_shutdown)) {
|
||||
process_due_timers(); // Process any due timers first
|
||||
|
||||
/* Check for SDL events with timeout */
|
||||
uint64_t to_ns = next_timeout_ns();
|
||||
if (to_ns == UINT64_MAX || to_ns > fallback_sleep) to_ns = fallback_sleep;
|
||||
|
||||
/* Convert nanoseconds to milliseconds for SDL_WaitEventTimeout */
|
||||
int timeout_ms = (int)(to_ns / 1000000ULL);
|
||||
if (timeout_ms < 1) timeout_ms = 1;
|
||||
|
||||
if (SDL_WaitEventTimeout(&event, timeout_ms)) {
|
||||
if (event.type == queue_event) {
|
||||
goto QUEUE;
|
||||
}
|
||||
/* Process other SDL events as needed */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Timeout occurred - check queues anyway */
|
||||
QUEUE:
|
||||
SDL_LockMutex(queue_mutex);
|
||||
cell_rt *actor = NULL;
|
||||
if (arrlen(main_ready_queue) > 0) {
|
||||
@@ -1686,8 +970,19 @@ int main(int argc, char **argv)
|
||||
}
|
||||
SDL_UnlockMutex(queue_mutex);
|
||||
|
||||
if (actor) {
|
||||
actor_turn(actor, 0);
|
||||
if (actor)
|
||||
actor_turn(actor);
|
||||
|
||||
uint64_t to_ns = next_timeout_ns();
|
||||
if (to_ns == UINT64_MAX) {
|
||||
// No timers pending, wait indefinitely
|
||||
pselect(0, NULL, NULL, NULL, NULL, NULL);
|
||||
} else {
|
||||
struct timespec timeout = {
|
||||
.tv_sec = to_ns / 1000000000,
|
||||
.tv_nsec = to_ns % 1000000000
|
||||
};
|
||||
pselect(0, NULL, NULL, NULL, &timeout, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1705,7 +1000,7 @@ int actor_exists(const char *id)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int JS_ArrayLength(JSContext *js, JSValue a)
|
||||
/*int JS_ArrayLength(JSContext *js, JSValue a)
|
||||
{
|
||||
JSValue length = JS_GetPropertyStr(js, a, "length");
|
||||
int len;
|
||||
@@ -1713,3 +1008,4 @@ int JS_ArrayLength(JSContext *js, JSValue a)
|
||||
JS_FreeValue(js,length);
|
||||
return len;
|
||||
}
|
||||
*/
|
||||
@@ -57,8 +57,7 @@ typedef struct cell_rt {
|
||||
JSValue *js_swapchains;
|
||||
|
||||
/* Protects JSContext usage */
|
||||
SDL_Mutex *mutex;
|
||||
SDL_Mutex *turn;
|
||||
SDL_Mutex *mutex; /* for access to the JSContext */
|
||||
SDL_Mutex *msg_mutex; /* For messages queue only */
|
||||
|
||||
char *id;
|
||||
@@ -111,8 +110,5 @@ int JS_ArrayLength(JSContext *js, JSValue a);
|
||||
|
||||
int prosperon_mount_core(void);
|
||||
|
||||
// Event watchers for SDL events
|
||||
extern char **event_watchers;
|
||||
extern SDL_Mutex *event_watchers_mutex;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "font.h"
|
||||
#include "datastream.h"
|
||||
#include "qjs_sdl.h"
|
||||
#include "qjs_sdl_input.h"
|
||||
#include "qjs_io.h"
|
||||
#include "qjs_fd.h"
|
||||
#include "transform.h"
|
||||
@@ -1619,11 +1620,11 @@ void ffi_load(JSContext *js)
|
||||
rt->init_wota = NULL;
|
||||
}
|
||||
|
||||
cell_rt *actor = JS_GetContextOpaque(js);
|
||||
JSValue actorsym = js_newsymbol(js, "actor symbol", 0);
|
||||
actor->actor_sym = JS_ValueToAtom(js, actorsym);
|
||||
JS_SetPropertyStr(js, hidden_fn, "ACTORDATA", JS_DupValue(js,actorsym));
|
||||
JS_FreeValue(js, actorsym);
|
||||
// cell_rt *actor = JS_GetContextOpaque(js);
|
||||
// JSValue actorsym = js_newsymbol(js, "actor symbol", 0);
|
||||
// actor->actor_sym = JS_ValueToAtom(js, actorsym);
|
||||
// JS_SetPropertyStr(js, hidden_fn, "ACTORDATA", JS_DupValue(js,actorsym));
|
||||
// JS_FreeValue(js, actorsym);
|
||||
JS_SetPropertyStr(js, prosp, "hidden", hidden_fn);
|
||||
|
||||
JS_FreeValue(js,globalThis);
|
||||
|
||||
130
source/qjs_sdl.c
130
source/qjs_sdl.c
@@ -23,136 +23,6 @@ void SDL_AudioStream_free(JSRuntime *rt, SDL_AudioStream *st) {
|
||||
QJSCLASS(SDL_Camera,)
|
||||
QJSCLASS(SDL_AudioStream,)
|
||||
|
||||
// Internal keymod function for input module
|
||||
static JSValue js_keymod(JSContext *js)
|
||||
{
|
||||
SDL_Keymod modstate = SDL_GetModState();
|
||||
JSValue ret = JS_NewObject(js);
|
||||
if (SDL_KMOD_CTRL & modstate)
|
||||
JS_SetPropertyStr(js,ret,"ctrl", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_SHIFT & modstate)
|
||||
JS_SetPropertyStr(js,ret,"shift", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_ALT & modstate)
|
||||
JS_SetPropertyStr(js,ret,"alt", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_GUI & modstate)
|
||||
JS_SetPropertyStr(js,ret,"super", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_NUM & modstate)
|
||||
JS_SetPropertyStr(js,ret,"numlock", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_CAPS & modstate)
|
||||
JS_SetPropertyStr(js,ret,"caps", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_SCROLL & modstate)
|
||||
JS_SetPropertyStr(js,ret,"scrolllock", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_MODE & modstate)
|
||||
JS_SetPropertyStr(js,ret,"mode", JS_NewBool(js,1));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// INPUT FUNCTIONS
|
||||
JSC_CCALL(input_mouse_lock, SDL_CaptureMouse(JS_ToBool(js,argv[0])))
|
||||
|
||||
JSC_CCALL(input_mouse_show,
|
||||
if (JS_ToBool(js,argv[0]))
|
||||
SDL_ShowCursor();
|
||||
else
|
||||
SDL_HideCursor();
|
||||
)
|
||||
|
||||
JSC_CCALL(input_keyname,
|
||||
return JS_NewString(js, SDL_GetKeyName(js2number(js,argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(input_keymod,
|
||||
return js_keymod(js);
|
||||
)
|
||||
|
||||
JSC_CCALL(input_mousestate,
|
||||
float x,y;
|
||||
SDL_MouseButtonFlags flags = SDL_GetMouseState(&x,&y);
|
||||
JSValue m = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js,m,"x", number2js(js,x));
|
||||
JS_SetPropertyStr(js,m,"y", number2js(js,y));
|
||||
|
||||
if (flags & SDL_BUTTON_LMASK)
|
||||
JS_SetPropertyStr(js, m, "left", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_MMASK)
|
||||
JS_SetPropertyStr(js, m, "middle", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_RMASK)
|
||||
JS_SetPropertyStr(js, m, "right", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X1MASK)
|
||||
JS_SetPropertyStr(js, m, "x1", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X2MASK)
|
||||
JS_SetPropertyStr(js, m, "x2", JS_NewBool(js, 1));
|
||||
|
||||
return m;
|
||||
)
|
||||
|
||||
// watch events
|
||||
extern char **event_watchers;
|
||||
extern SDL_Mutex *event_watchers_mutex;
|
||||
|
||||
JSC_CCALL(input_watch,
|
||||
/* Use js2actor to get the actor from the JS object */
|
||||
cell_rt *actor = js2actor(js, argv[0]);
|
||||
if (!actor)
|
||||
return JS_ThrowTypeError(js, "First argument must be a valid actor object");
|
||||
|
||||
SDL_LockMutex(event_watchers_mutex);
|
||||
|
||||
/* Check if already watching */
|
||||
int already_watching = 0;
|
||||
for (int i = 0; i < arrlen(event_watchers); i++) {
|
||||
if (strcmp(event_watchers[i], actor->id) == 0) {
|
||||
already_watching = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!already_watching)
|
||||
arrput(event_watchers, strdup(actor->id));
|
||||
|
||||
SDL_UnlockMutex(event_watchers_mutex);
|
||||
|
||||
return JS_UNDEFINED;
|
||||
)
|
||||
|
||||
JSC_CCALL(input_unwatch,
|
||||
/* Use js2actor to get the actor from the JS object */
|
||||
cell_rt *actor = js2actor(js, argv[0]);
|
||||
if (!actor)
|
||||
return JS_ThrowTypeError(js, "First argument must be a valid actor object");
|
||||
|
||||
SDL_LockMutex(event_watchers_mutex);
|
||||
|
||||
/* Find and remove from watchers */
|
||||
for (int i = 0; i < arrlen(event_watchers); i++) {
|
||||
if (strcmp(event_watchers[i], actor->id) == 0) {
|
||||
free(event_watchers[i]);
|
||||
arrdel(event_watchers, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockMutex(event_watchers_mutex);
|
||||
|
||||
return JS_UNDEFINED;
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_input_funcs[] = {
|
||||
MIST_FUNC_DEF(input, mouse_show, 1),
|
||||
MIST_FUNC_DEF(input, mouse_lock, 1),
|
||||
MIST_FUNC_DEF(input, keyname, 1),
|
||||
MIST_FUNC_DEF(input, keymod, 0),
|
||||
MIST_FUNC_DEF(input, mousestate, 0),
|
||||
MIST_FUNC_DEF(input, watch, 1),
|
||||
MIST_FUNC_DEF(input, unwatch, 1),
|
||||
};
|
||||
|
||||
JSValue js_input_use(JSContext *js) {
|
||||
JSValue mod = JS_NewObject(js);
|
||||
JS_SetPropertyFunctionList(js,mod,js_input_funcs,countof(js_input_funcs));
|
||||
return mod;
|
||||
}
|
||||
|
||||
// CAMERA FUNCTIONS
|
||||
|
||||
|
||||
717
source/qjs_sdl_input.c
Normal file
717
source/qjs_sdl_input.c
Normal file
@@ -0,0 +1,717 @@
|
||||
#include "qjs_sdl_input.h"
|
||||
#include "jsffi.h"
|
||||
#include "qjs_macros.h"
|
||||
#include "cell.h"
|
||||
#include "qjs_blob.h"
|
||||
#include "stb_ds.h"
|
||||
#include "qjs_actor.h"
|
||||
#include "qjs_wota.h"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
void input_system_init(void)
|
||||
{
|
||||
// No initialization needed for simplified system
|
||||
}
|
||||
|
||||
void input_system_cleanup(void)
|
||||
{
|
||||
// No cleanup needed for simplified system
|
||||
}
|
||||
|
||||
// Internal keymod function for input module
|
||||
static JSValue js_keymod(JSContext *js)
|
||||
{
|
||||
SDL_Keymod modstate = SDL_GetModState();
|
||||
JSValue ret = JS_NewObject(js);
|
||||
if (SDL_KMOD_CTRL & modstate)
|
||||
JS_SetPropertyStr(js,ret,"ctrl", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_SHIFT & modstate)
|
||||
JS_SetPropertyStr(js,ret,"shift", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_ALT & modstate)
|
||||
JS_SetPropertyStr(js,ret,"alt", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_GUI & modstate)
|
||||
JS_SetPropertyStr(js,ret,"super", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_NUM & modstate)
|
||||
JS_SetPropertyStr(js,ret,"numlock", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_CAPS & modstate)
|
||||
JS_SetPropertyStr(js,ret,"caps", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_SCROLL & modstate)
|
||||
JS_SetPropertyStr(js,ret,"scrolllock", JS_NewBool(js,1));
|
||||
if (SDL_KMOD_MODE & modstate)
|
||||
JS_SetPropertyStr(js,ret,"mode", JS_NewBool(js,1));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// INPUT FUNCTIONS
|
||||
JSC_CCALL(input_mouse_lock, SDL_CaptureMouse(JS_ToBool(js,argv[0])))
|
||||
|
||||
JSC_CCALL(input_mouse_show,
|
||||
if (JS_ToBool(js,argv[0]))
|
||||
SDL_ShowCursor();
|
||||
else
|
||||
SDL_HideCursor();
|
||||
)
|
||||
|
||||
JSC_CCALL(input_keyname,
|
||||
return JS_NewString(js, SDL_GetKeyName(js2number(js,argv[0])));
|
||||
)
|
||||
|
||||
JSC_CCALL(input_keymod,
|
||||
return js_keymod(js);
|
||||
)
|
||||
|
||||
JSC_CCALL(input_mousestate,
|
||||
float x,y;
|
||||
SDL_MouseButtonFlags flags = SDL_GetMouseState(&x,&y);
|
||||
JSValue m = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js,m,"x", number2js(js,x));
|
||||
JS_SetPropertyStr(js,m,"y", number2js(js,y));
|
||||
|
||||
if (flags & SDL_BUTTON_LMASK)
|
||||
JS_SetPropertyStr(js, m, "left", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_MMASK)
|
||||
JS_SetPropertyStr(js, m, "middle", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_RMASK)
|
||||
JS_SetPropertyStr(js, m, "right", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X1MASK)
|
||||
JS_SetPropertyStr(js, m, "x1", JS_NewBool(js, 1));
|
||||
if (flags & SDL_BUTTON_X2MASK)
|
||||
JS_SetPropertyStr(js, m, "x2", JS_NewBool(js, 1));
|
||||
|
||||
return m;
|
||||
)
|
||||
|
||||
// Event processing functions (moved from cell.c)
|
||||
|
||||
const char* event_type_to_string(Uint32 event_type) {
|
||||
switch (event_type) {
|
||||
// Application events
|
||||
case SDL_EVENT_QUIT: return "quit";
|
||||
case SDL_EVENT_TERMINATING: return "terminating";
|
||||
case SDL_EVENT_LOW_MEMORY: return "low_memory";
|
||||
case SDL_EVENT_WILL_ENTER_BACKGROUND: return "will_enter_background";
|
||||
case SDL_EVENT_DID_ENTER_BACKGROUND: return "did_enter_background";
|
||||
case SDL_EVENT_WILL_ENTER_FOREGROUND: return "will_enter_foreground";
|
||||
case SDL_EVENT_DID_ENTER_FOREGROUND: return "did_enter_foreground";
|
||||
case SDL_EVENT_LOCALE_CHANGED: return "locale_changed";
|
||||
case SDL_EVENT_SYSTEM_THEME_CHANGED: return "system_theme_changed";
|
||||
|
||||
// Display events
|
||||
case SDL_EVENT_DISPLAY_ORIENTATION: return "display_orientation";
|
||||
case SDL_EVENT_DISPLAY_ADDED: return "display_added";
|
||||
case SDL_EVENT_DISPLAY_REMOVED: return "display_removed";
|
||||
case SDL_EVENT_DISPLAY_MOVED: return "display_moved";
|
||||
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED: return "display_desktop_mode_changed";
|
||||
case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED: return "display_current_mode_changed";
|
||||
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED: return "display_content_scale_changed";
|
||||
|
||||
// Window events
|
||||
case SDL_EVENT_WINDOW_SHOWN: return "window_shown";
|
||||
case SDL_EVENT_WINDOW_HIDDEN: return "window_hidden";
|
||||
case SDL_EVENT_WINDOW_EXPOSED: return "window_exposed";
|
||||
case SDL_EVENT_WINDOW_MOVED: return "window_moved";
|
||||
case SDL_EVENT_WINDOW_RESIZED: return "window_resized";
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: return "window_pixel_size_changed";
|
||||
case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED: return "window_metal_view_resized";
|
||||
case SDL_EVENT_WINDOW_MINIMIZED: return "window_minimized";
|
||||
case SDL_EVENT_WINDOW_MAXIMIZED: return "window_maximized";
|
||||
case SDL_EVENT_WINDOW_RESTORED: return "window_restored";
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER: return "window_mouse_enter";
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE: return "window_mouse_leave";
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED: return "window_focus_gained";
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST: return "window_focus_lost";
|
||||
case SDL_EVENT_WINDOW_CLOSE_REQUESTED: return "window_close_requested";
|
||||
case SDL_EVENT_WINDOW_HIT_TEST: return "window_hit_test";
|
||||
case SDL_EVENT_WINDOW_ICCPROF_CHANGED: return "window_iccprof_changed";
|
||||
case SDL_EVENT_WINDOW_DISPLAY_CHANGED: return "window_display_changed";
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: return "window_display_scale_changed";
|
||||
case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED: return "window_safe_area_changed";
|
||||
case SDL_EVENT_WINDOW_OCCLUDED: return "window_occluded";
|
||||
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN: return "window_enter_fullscreen";
|
||||
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN: return "window_leave_fullscreen";
|
||||
case SDL_EVENT_WINDOW_DESTROYED: return "window_destroyed";
|
||||
case SDL_EVENT_WINDOW_HDR_STATE_CHANGED: return "window_hdr_state_changed";
|
||||
|
||||
// Keyboard events
|
||||
case SDL_EVENT_KEY_DOWN: return "key_down";
|
||||
case SDL_EVENT_KEY_UP: return "key_up";
|
||||
case SDL_EVENT_TEXT_EDITING: return "text_editing";
|
||||
case SDL_EVENT_TEXT_INPUT: return "text_input";
|
||||
case SDL_EVENT_KEYMAP_CHANGED: return "keymap_changed";
|
||||
case SDL_EVENT_KEYBOARD_ADDED: return "keyboard_added";
|
||||
case SDL_EVENT_KEYBOARD_REMOVED: return "keyboard_removed";
|
||||
case SDL_EVENT_TEXT_EDITING_CANDIDATES: return "text_editing_candidates";
|
||||
|
||||
// Mouse events
|
||||
case SDL_EVENT_MOUSE_MOTION: return "mouse_motion";
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN: return "mouse_button_down";
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP: return "mouse_button_up";
|
||||
case SDL_EVENT_MOUSE_WHEEL: return "mouse_wheel";
|
||||
case SDL_EVENT_MOUSE_ADDED: return "mouse_added";
|
||||
case SDL_EVENT_MOUSE_REMOVED: return "mouse_removed";
|
||||
|
||||
// Joystick events
|
||||
case SDL_EVENT_JOYSTICK_AXIS_MOTION: return "joystick_axis_motion";
|
||||
case SDL_EVENT_JOYSTICK_BALL_MOTION: return "joystick_ball_motion";
|
||||
case SDL_EVENT_JOYSTICK_HAT_MOTION: return "joystick_hat_motion";
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_DOWN: return "joystick_button_down";
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_UP: return "joystick_button_up";
|
||||
case SDL_EVENT_JOYSTICK_ADDED: return "joystick_added";
|
||||
case SDL_EVENT_JOYSTICK_REMOVED: return "joystick_removed";
|
||||
case SDL_EVENT_JOYSTICK_BATTERY_UPDATED: return "joystick_battery_updated";
|
||||
case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE: return "joystick_update_complete";
|
||||
|
||||
// Gamepad events
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION: return "gamepad_axis_motion";
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN: return "gamepad_button_down";
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP: return "gamepad_button_up";
|
||||
case SDL_EVENT_GAMEPAD_ADDED: return "gamepad_added";
|
||||
case SDL_EVENT_GAMEPAD_REMOVED: return "gamepad_removed";
|
||||
case SDL_EVENT_GAMEPAD_REMAPPED: return "gamepad_remapped";
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN: return "gamepad_touchpad_down";
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION: return "gamepad_touchpad_motion";
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP: return "gamepad_touchpad_up";
|
||||
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: return "gamepad_sensor_update";
|
||||
case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE: return "gamepad_update_complete";
|
||||
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED: return "gamepad_steam_handle_updated";
|
||||
|
||||
// Touch events
|
||||
case SDL_EVENT_FINGER_DOWN: return "finger_down";
|
||||
case SDL_EVENT_FINGER_UP: return "finger_up";
|
||||
case SDL_EVENT_FINGER_MOTION: return "finger_motion";
|
||||
|
||||
// Clipboard events
|
||||
case SDL_EVENT_CLIPBOARD_UPDATE: return "clipboard_update";
|
||||
|
||||
// Drag and drop events
|
||||
case SDL_EVENT_DROP_FILE: return "drop_file";
|
||||
case SDL_EVENT_DROP_TEXT: return "drop_text";
|
||||
case SDL_EVENT_DROP_BEGIN: return "drop_begin";
|
||||
case SDL_EVENT_DROP_COMPLETE: return "drop_complete";
|
||||
case SDL_EVENT_DROP_POSITION: return "drop_position";
|
||||
|
||||
// Audio device events
|
||||
case SDL_EVENT_AUDIO_DEVICE_ADDED: return "audio_device_added";
|
||||
case SDL_EVENT_AUDIO_DEVICE_REMOVED: return "audio_device_removed";
|
||||
case SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED: return "audio_device_format_changed";
|
||||
|
||||
// Sensor events
|
||||
case SDL_EVENT_SENSOR_UPDATE: return "sensor_update";
|
||||
|
||||
// Pen events
|
||||
case SDL_EVENT_PEN_PROXIMITY_IN: return "pen_proximity_in";
|
||||
case SDL_EVENT_PEN_PROXIMITY_OUT: return "pen_proximity_out";
|
||||
case SDL_EVENT_PEN_DOWN: return "pen_down";
|
||||
case SDL_EVENT_PEN_UP: return "pen_up";
|
||||
case SDL_EVENT_PEN_BUTTON_DOWN: return "pen_button_down";
|
||||
case SDL_EVENT_PEN_BUTTON_UP: return "pen_button_up";
|
||||
case SDL_EVENT_PEN_MOTION: return "pen_motion";
|
||||
case SDL_EVENT_PEN_AXIS: return "pen_axis";
|
||||
|
||||
// Camera events
|
||||
case SDL_EVENT_CAMERA_DEVICE_ADDED: return "camera_device_added";
|
||||
case SDL_EVENT_CAMERA_DEVICE_REMOVED: return "camera_device_removed";
|
||||
case SDL_EVENT_CAMERA_DEVICE_APPROVED: return "camera_device_approved";
|
||||
case SDL_EVENT_CAMERA_DEVICE_DENIED: return "camera_device_denied";
|
||||
|
||||
// Render events
|
||||
case SDL_EVENT_RENDER_TARGETS_RESET: return "render_targets_reset";
|
||||
case SDL_EVENT_RENDER_DEVICE_RESET: return "render_device_reset";
|
||||
case SDL_EVENT_RENDER_DEVICE_LOST: return "render_device_lost";
|
||||
|
||||
// User event (assuming it should be included)
|
||||
case SDL_EVENT_USER: return "user";
|
||||
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char* mouse_button_to_string(int mouse) {
|
||||
switch (mouse) {
|
||||
case SDL_BUTTON_LEFT: return "left";
|
||||
case SDL_BUTTON_MIDDLE: return "middle";
|
||||
case SDL_BUTTON_RIGHT: return "right";
|
||||
case SDL_BUTTON_X1: return "x1";
|
||||
case SDL_BUTTON_X2: return "x2";
|
||||
default: return "left";
|
||||
}
|
||||
}
|
||||
|
||||
static void wota_write_vec2(WotaBuffer *wb, double x, double y) {
|
||||
// We'll store as WOTA_ARR of length 2, then two numbers
|
||||
wota_write_array(wb, 2);
|
||||
wota_write_number(wb, x);
|
||||
wota_write_number(wb, y);
|
||||
}
|
||||
|
||||
static int event2wota_count_props(const SDL_Event *event)
|
||||
{
|
||||
// We always store at least "type" and "timestamp".
|
||||
int count = 2;
|
||||
|
||||
switch (event->type) {
|
||||
|
||||
case SDL_EVENT_AUDIO_DEVICE_ADDED:
|
||||
case SDL_EVENT_AUDIO_DEVICE_REMOVED:
|
||||
count += 2; // which, recording
|
||||
break;
|
||||
|
||||
case SDL_EVENT_DISPLAY_ORIENTATION:
|
||||
case SDL_EVENT_DISPLAY_ADDED:
|
||||
case SDL_EVENT_DISPLAY_REMOVED:
|
||||
case SDL_EVENT_DISPLAY_MOVED:
|
||||
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
|
||||
case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED:
|
||||
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:
|
||||
count += 3; // which, data1, data2
|
||||
break;
|
||||
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
count += 5;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
// window, which, scroll, mouse => 4 extra
|
||||
count += 4;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
// window, which, down, button, clicks, mouse => 6 extra
|
||||
count += 6;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_SENSOR_UPDATE:
|
||||
// which, sensor_timestamp => 2 extra
|
||||
count += 2;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
case SDL_EVENT_KEY_UP:
|
||||
// window, which, down, repeat, key, scancode, mod => 7 extra
|
||||
count += 7;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_FINGER_MOTION:
|
||||
case SDL_EVENT_FINGER_DOWN:
|
||||
case SDL_EVENT_FINGER_UP:
|
||||
// touch, finger, pos, d_pos, pressure, window => 6 extra
|
||||
count += 6;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_DROP_BEGIN:
|
||||
case SDL_EVENT_DROP_FILE:
|
||||
case SDL_EVENT_DROP_TEXT:
|
||||
case SDL_EVENT_DROP_COMPLETE:
|
||||
case SDL_EVENT_DROP_POSITION:
|
||||
// window, pos, data, source => 4 extra
|
||||
count += 4;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_TEXT_INPUT:
|
||||
// window, text, mod => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_CAMERA_DEVICE_APPROVED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_REMOVED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_ADDED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_DENIED:
|
||||
// which => 1 extra
|
||||
count += 1;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_CLIPBOARD_UPDATE:
|
||||
// owner => 1 extra
|
||||
count += 1;
|
||||
break;
|
||||
|
||||
/* Window events (just group them all together) */
|
||||
case SDL_EVENT_WINDOW_SHOWN:
|
||||
case SDL_EVENT_WINDOW_HIDDEN:
|
||||
case SDL_EVENT_WINDOW_EXPOSED:
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||
case SDL_EVENT_WINDOW_MAXIMIZED:
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
|
||||
case SDL_EVENT_WINDOW_HIT_TEST:
|
||||
case SDL_EVENT_WINDOW_ICCPROF_CHANGED:
|
||||
case SDL_EVENT_WINDOW_DISPLAY_CHANGED:
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
|
||||
case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED:
|
||||
case SDL_EVENT_WINDOW_OCCLUDED:
|
||||
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
|
||||
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
|
||||
case SDL_EVENT_WINDOW_DESTROYED:
|
||||
case SDL_EVENT_WINDOW_HDR_STATE_CHANGED:
|
||||
// which, data1, data2 => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_JOYSTICK_ADDED:
|
||||
case SDL_EVENT_JOYSTICK_REMOVED:
|
||||
case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE:
|
||||
// which => 1 extra
|
||||
count += 1;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
|
||||
// which, axis, value => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_JOYSTICK_BALL_MOTION:
|
||||
// which, ball, rel => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_UP:
|
||||
// which, button, down => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
case SDL_EVENT_GAMEPAD_REMAPPED:
|
||||
case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE:
|
||||
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED:
|
||||
// which => 1 extra
|
||||
count += 1;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
||||
// which, axis, value => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP:
|
||||
// which, button, down => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN:
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP:
|
||||
// which, touchpad, finger, pos, pressure => 5 extra
|
||||
count += 5;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE:
|
||||
// which, sensor, sensor_timestamp => 3 extra
|
||||
count += 3;
|
||||
break;
|
||||
|
||||
case SDL_EVENT_USER:
|
||||
// cb => 1 extra
|
||||
count += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void event2wota_write(WotaBuffer *wb, const SDL_Event *e, int c) {
|
||||
wota_write_record(wb, (unsigned long long)c);
|
||||
wota_write_text(wb, "type");
|
||||
wota_write_text(wb, event_type_to_string(e->type));
|
||||
wota_write_text(wb, "timestamp");
|
||||
wota_write_number(wb, (double)e->common.timestamp);
|
||||
switch(e->type) {
|
||||
case SDL_EVENT_AUDIO_DEVICE_ADDED:
|
||||
case SDL_EVENT_AUDIO_DEVICE_REMOVED:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->adevice.which);
|
||||
wota_write_text(wb, "recording");
|
||||
wota_write_sym(wb, e->adevice.recording ? WOTA_TRUE : WOTA_FALSE);
|
||||
break;
|
||||
case SDL_EVENT_DISPLAY_ORIENTATION:
|
||||
case SDL_EVENT_DISPLAY_ADDED:
|
||||
case SDL_EVENT_DISPLAY_REMOVED:
|
||||
case SDL_EVENT_DISPLAY_MOVED:
|
||||
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
|
||||
case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED:
|
||||
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->display.displayID);
|
||||
wota_write_text(wb, "data1");
|
||||
wota_write_number(wb, (double)e->display.data1);
|
||||
wota_write_text(wb, "data2");
|
||||
wota_write_number(wb, (double)e->display.data2);
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->motion.windowID);
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->motion.which);
|
||||
wota_write_text(wb, "state");
|
||||
wota_write_number(wb, (double)e->motion.state);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->motion.x, (double)e->motion.y);
|
||||
wota_write_text(wb, "d_pos");
|
||||
wota_write_vec2(wb, (double)e->motion.xrel, (double)e->motion.yrel);
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->wheel.windowID);
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->wheel.which);
|
||||
wota_write_text(wb, "scroll");
|
||||
wota_write_vec2(wb, (double)e->wheel.x, (double)e->wheel.y);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->wheel.mouse_x, (double)e->wheel.mouse_y);
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->button.windowID);
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->button.which);
|
||||
wota_write_text(wb, "down");
|
||||
wota_write_sym(wb, e->button.down ? WOTA_TRUE : WOTA_FALSE);
|
||||
wota_write_text(wb, "button");
|
||||
wota_write_text(wb, mouse_button_to_string(e->button.button));
|
||||
wota_write_text(wb, "clicks");
|
||||
wota_write_number(wb, (double)e->button.clicks);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->button.x, (double)e->button.y);
|
||||
break;
|
||||
case SDL_EVENT_SENSOR_UPDATE:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->sensor.which);
|
||||
wota_write_text(wb, "sensor_timestamp");
|
||||
wota_write_number(wb, (double)e->sensor.sensor_timestamp);
|
||||
break;
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
case SDL_EVENT_KEY_UP:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->key.windowID);
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->key.which);
|
||||
wota_write_text(wb, "down");
|
||||
wota_write_sym(wb, e->key.down ? WOTA_TRUE : WOTA_FALSE);
|
||||
wota_write_text(wb, "repeat");
|
||||
wota_write_sym(wb, e->key.repeat ? WOTA_TRUE : WOTA_FALSE);
|
||||
wota_write_text(wb, "key");
|
||||
wota_write_number(wb, (double)e->key.key);
|
||||
wota_write_text(wb, "scancode");
|
||||
wota_write_number(wb, (double)e->key.scancode);
|
||||
wota_write_text(wb, "mod");
|
||||
wota_write_number(wb, 0);
|
||||
break;
|
||||
case SDL_EVENT_FINGER_MOTION:
|
||||
case SDL_EVENT_FINGER_DOWN:
|
||||
case SDL_EVENT_FINGER_UP:
|
||||
wota_write_text(wb, "touch");
|
||||
wota_write_number(wb, (double)e->tfinger.touchID);
|
||||
wota_write_text(wb, "finger");
|
||||
wota_write_number(wb, (double)e->tfinger.fingerID);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->tfinger.x, (double)e->tfinger.y);
|
||||
wota_write_text(wb, "d_pos");
|
||||
wota_write_vec2(wb, (double)e->tfinger.dx, (double)e->tfinger.dy);
|
||||
wota_write_text(wb, "pressure");
|
||||
wota_write_number(wb, (double)e->tfinger.pressure);
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->key.windowID);
|
||||
break;
|
||||
case SDL_EVENT_DROP_BEGIN:
|
||||
case SDL_EVENT_DROP_FILE:
|
||||
case SDL_EVENT_DROP_TEXT:
|
||||
case SDL_EVENT_DROP_COMPLETE:
|
||||
case SDL_EVENT_DROP_POSITION:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->drop.windowID);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->drop.x, (double)e->drop.y);
|
||||
wota_write_text(wb, "data");
|
||||
wota_write_text(wb, e->drop.data ? e->drop.data : "");
|
||||
wota_write_text(wb, "source");
|
||||
wota_write_text(wb, e->drop.source ? e->drop.source : "");
|
||||
break;
|
||||
case SDL_EVENT_TEXT_INPUT:
|
||||
wota_write_text(wb, "window");
|
||||
wota_write_number(wb, (double)e->text.windowID);
|
||||
wota_write_text(wb, "text");
|
||||
wota_write_text(wb, e->text.text);
|
||||
wota_write_text(wb, "mod");
|
||||
wota_write_number(wb, 0);
|
||||
break;
|
||||
case SDL_EVENT_CAMERA_DEVICE_APPROVED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_REMOVED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_ADDED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_DENIED:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->cdevice.which);
|
||||
break;
|
||||
case SDL_EVENT_CLIPBOARD_UPDATE:
|
||||
wota_write_text(wb, "owner");
|
||||
wota_write_sym(wb, e->clipboard.owner ? WOTA_TRUE : WOTA_FALSE);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_SHOWN:
|
||||
case SDL_EVENT_WINDOW_HIDDEN:
|
||||
case SDL_EVENT_WINDOW_EXPOSED:
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||
case SDL_EVENT_WINDOW_MAXIMIZED:
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
|
||||
case SDL_EVENT_WINDOW_HIT_TEST:
|
||||
case SDL_EVENT_WINDOW_ICCPROF_CHANGED:
|
||||
case SDL_EVENT_WINDOW_DISPLAY_CHANGED:
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
|
||||
case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED:
|
||||
case SDL_EVENT_WINDOW_OCCLUDED:
|
||||
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
|
||||
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
|
||||
case SDL_EVENT_WINDOW_DESTROYED:
|
||||
case SDL_EVENT_WINDOW_HDR_STATE_CHANGED:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->window.windowID);
|
||||
wota_write_text(wb, "data1");
|
||||
wota_write_number(wb, (double)e->window.data1);
|
||||
wota_write_text(wb, "data2");
|
||||
wota_write_number(wb, (double)e->window.data2);
|
||||
break;
|
||||
case SDL_EVENT_JOYSTICK_ADDED:
|
||||
case SDL_EVENT_JOYSTICK_REMOVED:
|
||||
case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->jdevice.which);
|
||||
break;
|
||||
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->jaxis.which);
|
||||
wota_write_text(wb, "axis");
|
||||
wota_write_number(wb, (double)e->jaxis.axis);
|
||||
wota_write_text(wb, "value");
|
||||
wota_write_number(wb, (double)e->jaxis.value);
|
||||
break;
|
||||
case SDL_EVENT_JOYSTICK_BALL_MOTION:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->jball.which);
|
||||
wota_write_text(wb, "ball");
|
||||
wota_write_number(wb, (double)e->jball.ball);
|
||||
wota_write_text(wb, "rel");
|
||||
wota_write_vec2(wb, (double)e->jball.xrel, (double)e->jball.yrel);
|
||||
break;
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
|
||||
case SDL_EVENT_JOYSTICK_BUTTON_UP:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->jbutton.which);
|
||||
wota_write_text(wb, "button");
|
||||
wota_write_number(wb, (double)e->jbutton.button);
|
||||
wota_write_text(wb, "down");
|
||||
wota_write_sym(wb, e->jbutton.down ? WOTA_TRUE : WOTA_FALSE);
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
case SDL_EVENT_GAMEPAD_REMAPPED:
|
||||
case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE:
|
||||
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->gdevice.which);
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->gaxis.which);
|
||||
wota_write_text(wb, "axis");
|
||||
wota_write_number(wb, (double)e->gaxis.axis);
|
||||
wota_write_text(wb, "value");
|
||||
wota_write_number(wb, (double)e->gaxis.value);
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->gbutton.which);
|
||||
wota_write_text(wb, "button");
|
||||
wota_write_number(wb, (double)e->gbutton.button);
|
||||
wota_write_text(wb, "down");
|
||||
wota_write_sym(wb, e->gbutton.down ? WOTA_TRUE : WOTA_FALSE);
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN:
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->gtouchpad.which);
|
||||
wota_write_text(wb, "touchpad");
|
||||
wota_write_number(wb, (double)e->gtouchpad.touchpad);
|
||||
wota_write_text(wb, "finger");
|
||||
wota_write_number(wb, (double)e->gtouchpad.finger);
|
||||
wota_write_text(wb, "pos");
|
||||
wota_write_vec2(wb, (double)e->gtouchpad.x, (double)e->gtouchpad.y);
|
||||
wota_write_text(wb, "pressure");
|
||||
wota_write_number(wb, (double)e->gtouchpad.pressure);
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE:
|
||||
wota_write_text(wb, "which");
|
||||
wota_write_number(wb, (double)e->gsensor.which);
|
||||
wota_write_text(wb, "sensor");
|
||||
wota_write_number(wb, (double)e->gsensor.sensor);
|
||||
wota_write_text(wb, "sensor_timestamp");
|
||||
wota_write_number(wb, (double)e->gsensor.sensor_timestamp);
|
||||
break;
|
||||
case SDL_EVENT_USER:
|
||||
wota_write_text(wb, "cb");
|
||||
wota_write_number(wb, (double)(uintptr_t)e->user.data1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static WotaBuffer event2wota(const SDL_Event *event) {
|
||||
WotaBuffer wb;
|
||||
wota_buffer_init(&wb, 8);
|
||||
int n = event2wota_count_props(event);
|
||||
event2wota_write(&wb, event, n);
|
||||
return wb;
|
||||
}
|
||||
|
||||
// Get all events directly from SDL event queue
|
||||
JSC_CCALL(input_get_events,
|
||||
JSValue events_array = JS_NewArray(js);
|
||||
SDL_Event event;
|
||||
int event_count = 0;
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
WotaBuffer wb = event2wota(&event);
|
||||
JSValue event_obj = wota2value(js, wb.data);
|
||||
JS_SetPropertyUint32(js, events_array, event_count, event_obj);
|
||||
wota_buffer_free(&wb);
|
||||
event_count++;
|
||||
}
|
||||
|
||||
return events_array;
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_input_funcs[] = {
|
||||
MIST_FUNC_DEF(input, mouse_show, 1),
|
||||
MIST_FUNC_DEF(input, mouse_lock, 1),
|
||||
MIST_FUNC_DEF(input, keyname, 1),
|
||||
MIST_FUNC_DEF(input, keymod, 0),
|
||||
MIST_FUNC_DEF(input, mousestate, 0),
|
||||
MIST_FUNC_DEF(input, get_events, 0),
|
||||
};
|
||||
|
||||
JSValue js_input_use(JSContext *js) {
|
||||
JSValue mod = JS_NewObject(js);
|
||||
JS_SetPropertyFunctionList(js,mod,js_input_funcs,countof(js_input_funcs));
|
||||
return mod;
|
||||
}
|
||||
18
source/qjs_sdl_input.h
Normal file
18
source/qjs_sdl_input.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef QJS_SDL_INPUT_H
|
||||
#define QJS_SDL_INPUT_H
|
||||
|
||||
#include <quickjs.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
// Initialization and cleanup functions
|
||||
void input_system_init(void);
|
||||
void input_system_cleanup(void);
|
||||
|
||||
// Event conversion functions
|
||||
const char* event_type_to_string(Uint32 event_type);
|
||||
const char* mouse_button_to_string(int mouse);
|
||||
|
||||
// JavaScript module entry point
|
||||
JSValue js_input_use(JSContext *js);
|
||||
|
||||
#endif // QJS_SDL_INPUT_H
|
||||
Reference in New Issue
Block a user