1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
/**
* @file
* Unified application runner, event pipeline, and presentation context.
*
* Implements the inverted lifecycle architecture for modern cross-platform
* applications (games, IDEs, and desktop tools). Instead of managing manual
* dispatch/poll/flush pumps, the application provides event and frame callbacks
* to yasl_run(), which drives platform runloops, display pacing, and live resizing.
*/
#ifndef YASL_APP_H
#define YASL_APP_H
#include "yasl/yasl.h"
#include "yasl/loop.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Application callback return status. */
typedef enum yasl_app_result {
YASL_APP_CONTINUE = 0, /**< Continue running the application. */
YASL_APP_QUIT, /**< Request graceful termination of yasl_run(). */
YASL_APP_ERROR, /**< Request orderly cleanup and a failing run result. */
} yasl_app_result;
/** Migration adapter; prefer yasl_frame_present() from yasl.h. */
YASL_API bool yasl_frame_present_cpu(struct yasl_frame *frame,
const struct yasl_rect2i *dirty_rects, int count);
/**
* Safely post a custom user event to the main event loop from ANY thread.
* Wakes the display loop and delivers YASL_EVENT_USER to the event callback.
* @param d Display.
* @param s Optional target surface, or NULL.
* @param code Application-defined message code (yasl_user_event.code).
* @param payload Arbitrary pointer passed through to the event.
* @param size Optional payload size.
* @return true if queued; false if memory failed or d is not run by yasl_run().
* Migration adapter: keep s alive through the call, and stop producers before
* shutdown. Prefer yasl_display_post() with a captured ID and release callback
* in either loop style; legacy payloads have no cancellation cleanup.
*/
YASL_API bool yasl_post_event(struct yasl_display *d, struct yasl_surface *s,
uint32_t code, void *payload, size_t size);
/**
* Watch an open file descriptor or socket for poll-style readiness in the main loop.
* @param d Display.
* @param fd Open file descriptor (e.g. LSP stdout pipe or socket).
* @param poll_events Poll bitmask (e.g. POLLIN, POLLOUT).
* @param cb Readiness callback run on the main thread.
* @param ud Userdata.
* @return Positive watch ID, or -1 on failure.
*/
YASL_API int yasl_app_watch_fd(struct yasl_display *d, int fd, short poll_events,
int (*cb)(int fd, short revents, void *ud), void *ud);
/**
* Unregister a file watch.
* @param d Display.
* @param watch_id Watch ID returned by yasl_app_watch_fd().
*/
YASL_API void yasl_app_unwatch_fd(struct yasl_display *d, int watch_id);
/**
* Schedule a repeating or one-shot timer on the display's event loop.
* @param d Display.
* @param interval_ns Delay in monotonic nanoseconds.
* @param cb Callback returning next interval in nanoseconds, or 0 to stop.
* @param ud Userdata.
* @return Positive timer ID, or 0 on failure.
*/
YASL_API yasl_timer_id yasl_app_add_timer(struct yasl_display *d, uint64_t interval_ns,
yasl_timer_cb cb, void *ud);
/**
* Cancel an active timer.
* @param d Display.
* @param id Timer ID returned by yasl_app_add_timer().
*/
YASL_API void yasl_app_del_timer(struct yasl_display *d, yasl_timer_id id);
/** Application callbacks descriptor passed to yasl_run(). */
struct yasl_app_desc {
/** Application identifier, e.g. "org.example.app". */
const char *app_id;
/** Desired backend; YASL_BACKEND_AUTO chooses native with fallback. */
enum yasl_backend backend;
/** User data passed to all callbacks. */
void *userdata;
/**
* Optional toplevel created before init(), with its first frame requested.
* Borrowed for the call; spec cbs and ud are ignored as for any runner window.
* yasl_run() returns an error without calling init() if creation fails.
*/
const struct yasl_window_spec *window;
/**
* Optional; called once after display and event machinery initialization.
* Use this to create further windows and initialize application resources.
* Return YASL_APP_CONTINUE, YASL_APP_QUIT, or YASL_APP_ERROR.
*/
enum yasl_app_result (*init)(void *ud, struct yasl_display *d);
/**
* Unified event handler for input, window and user events, in display-wide enqueue order.
* Event payloads and borrowed strings are valid for the duration of the callback.
* INPUT_RESET has no payload and requires clearing held application input.
* Return YASL_APP_CONTINUE, YASL_APP_QUIT, or YASL_APP_ERROR. Optional; without it, a
* WINDOW_CLOSE request on any window stops yasl_run().
*/
enum yasl_app_result (*event)(void *ud, const struct yasl_event *ev);
/**
* Invoked when a surface needs to present a frame.
* Synchronized automatically with display pacing and live window resizing.
*/
void (*frame)(void *ud, struct yasl_surface *s, struct yasl_frame *frame);
/**
* Called right before the display is closed and yasl_run() exits.
* Destroy remaining surfaces and release application resources here.
*/
void (*quit)(void *ud, struct yasl_display *d);
};
/** Request orderly exit from any display-thread callback; ERROR returns failure. */
YASL_API void yasl_app_exit(struct yasl_display *d, enum yasl_app_result result);
/** Borrow the optional desc.window surface during init or later; NULL if absent/destroyed. */
YASL_API struct yasl_surface *yasl_app_window(struct yasl_display *d);
/**
* Run the application with the inverted lifecycle runner.
* Handles the display event loop, live-resizing, pacing, and cleanup.
* @param desc Application callbacks and options.
* @return 0 on orderly exit, or non-zero on error.
* Display quit notifications stop the runner; connection loss and dispatch
* failures return an error after application cleanup.
*/
YASL_API int yasl_run(const struct yasl_app_desc *desc);
#ifdef __cplusplus
}
#endif
#endif /* YASL_APP_H */
|