| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- using Astralis;
- using Invercargill;
- using Invercargill.DataStructures;
- using Inversion;
- using Spry;
- /**
- * AuroraSseEndpoint - Singleton SSE endpoint for aurora updates
- *
- * Broadcasts aurora canvas and stats updates to all connected clients
- * when aurora actions are triggered (BoostSolarWind, CalmAurora, etc.)
- *
- * Uses the Astralis SseEndpoint pattern - NOT continuations, since
- * continuations are for per-connection streaming, not broadcasting.
- */
- public class AuroraSseEndpoint : SseEndpoint {
-
- private AuroraState aurora_state;
-
- public AuroraSseEndpoint(AuroraState aurora_state) {
- this.aurora_state = aurora_state;
- }
-
- /// Retry interval: clients should wait 2 seconds before reconnecting
- public override uint retry_interval { get { return 2000; } }
-
- /// Called when a new client connects - send current state
- public override async void new_connection(HttpContext http_context, RouteContext route_context, SseStream stream) {
- print(@"Aurora SSE client connected (total: $(get_open_streams().length))\n");
-
- // Send current aurora state to new client
- try {
- yield send_aurora_update(stream);
- } catch (Error e) {
- print(@"Failed to send aurora update: $(e.message)\n");
- }
-
- stream.disconnected.connect(() => {
- print(@"Aurora SSE client disconnected\n");
- });
- }
-
- /// Boost solar wind and broadcast update
- public async void boost_solar_wind() {
- aurora_state.boost_solar_wind();
- yield broadcast_aurora_update();
- }
-
- /// Calm aurora and broadcast update
- public async void calm() {
- aurora_state.calm();
- yield broadcast_aurora_update();
- }
-
- /// Shift colors and broadcast update
- public async void shift_colors() {
- aurora_state.shift_colors();
- yield broadcast_aurora_update();
- }
-
- /// Add wave and broadcast update
- public async void add_wave() {
- aurora_state.add_wave();
- yield broadcast_aurora_update();
- }
-
- /// Broadcast aurora update to all connected clients
- private async void broadcast_aurora_update() {
- try {
- // Create canvas HTML
- string canvas_html = build_canvas_html();
- var canvas_event = new SseEvent.with_type("aurora-canvas", canvas_html);
-
- // Create stats HTML
- string stats_html = build_stats_html();
- var stats_event = new SseEvent.with_type("aurora-stats", stats_html);
-
- // Broadcast both events
- yield broadcast_event(canvas_event);
- yield broadcast_event(stats_event);
- } catch (Error e) {
- printerr(@"Failed to broadcast aurora update: $(e.message)\n");
- }
- }
-
- /// Send aurora update to a single stream (for new connections)
- private async void send_aurora_update(SseStream stream) throws Error {
- string canvas_html = build_canvas_html();
- yield stream.send_event(new SseEvent.with_type("aurora-canvas", canvas_html));
-
- string stats_html = build_stats_html();
- yield stream.send_event(new SseEvent.with_type("aurora-stats", stats_html));
- }
-
- /// Build the canvas HTML with all wave components
- private string build_canvas_html() {
- var builder = new StringBuilder();
- int wave_num = 0;
- foreach (var wave in aurora_state.get_waves()) {
- // Build the wave div with inline styles
- builder.append(@"<div class=\"aurora-wave\" style=\"--wave-y: $(wave.y_offset)%%; --wave-amplitude: $(wave.amplitude)px; --wave-freq: $(wave.frequency); --wave-color1: $(wave.color1); --wave-color2: $(wave.color2); --wave-opacity: $(wave.opacity); --wave-delay: $(wave.animation_delay)s; animation-delay: var(--wave-delay);\"></div>");
- wave_num++;
- }
- return builder.str;
- }
-
- /// Build the stats HTML
- private string build_stats_html() {
- return @"<div class=\"aurora-stat\"><div class=\"aurora-stat-value\">%.1f km/s</div><div class=\"aurora-stat-label\">Solar Wind</div></div><div class=\"aurora-stat\"><div class=\"aurora-stat-value\">$(aurora_state.wave_count)</div><div class=\"aurora-stat-label\">Waves</div></div><div class=\"aurora-stat\"><div class=\"aurora-stat-value\">%.0f%%</div><div class=\"aurora-stat-label\">Intensity</div></div><div class=\"aurora-stat\"><div class=\"aurora-stat-value\">$(aurora_state.color_mode)</div><div class=\"aurora-stat-label\">Color Mode</div></div>".printf(
- aurora_state.solar_wind_speed,
- aurora_state.intensity * 100
- );
- }
- }
|