From cf52424fb6d1a3dff431598d236a7808dbc63a30 Mon Sep 17 00:00:00 2001 From: Dannii Willis Date: Mon, 17 Apr 2023 12:11:24 +1000 Subject: [PATCH] Make GlkRunner async where necessary --- .../FrankenDrift.GlkRunner.AsyncGlk/Main.cs | 20 ++---- .../frankendrift.js | 9 +-- .../FrankenDrift.GlkRunner.Gargoyle/Main.cs | 16 ++--- .../FrankenDrift.GlkRunner.WinGlk/Main.cs | 15 ++-- .../FrankenDrift.GlkRunner/GlkApi.cs | 6 +- .../FrankenDrift.GlkRunner/GlkHtmlWin.cs | 71 +++++++++---------- .../FrankenDrift.GlkRunner/GlkSession.cs | 12 +++- 7 files changed, 66 insertions(+), 83 deletions(-) diff --git a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.AsyncGlk/Main.cs b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.AsyncGlk/Main.cs index a782e58..b510839 100644 --- a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.AsyncGlk/Main.cs +++ b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.AsyncGlk/Main.cs @@ -39,8 +39,6 @@ internal static partial class AsyncGlk_imports internal static partial void glk_request_char_event(IntPtr winId); [JSImport("glk_request_hyperlink_event", "main.js")] internal static partial void glk_request_hyperlink_event(IntPtr winId); - [JSImport("glk_request_line_event", "main.js")] - internal static partial void glk_request_line_event(IntPtr win, [JSMarshalAs] Span buf, int initlen); [JSImport("glk_request_line_event_uni", "main.js")] internal static partial void glk_request_line_event_uni(IntPtr win, [JSMarshalAs] Span buf, int initlen); [JSImport("glk_request_timer_events", "main.js")] @@ -55,8 +53,6 @@ internal static partial class AsyncGlk_imports internal static partial void glk_set_window(IntPtr winId); [JSImport("glk_stream_open_file", "main.js")] internal static partial IntPtr glk_stream_open_file(IntPtr fileref, int fmode, int rock); - [JSImport("glk_stream_open_memory", "main.js")] - internal static partial IntPtr glk_stream_open_memory([JSMarshalAs] Span buf, int mode, int rock); [JSImport("glk_stream_set_position", "main.js")] internal static partial void glk_stream_set_position(IntPtr stream, int pos, int seekMode); [JSImport("glk_stylehint_set", "main.js")] @@ -125,8 +121,7 @@ public uint glk_image_get_info(uint imageId, ref uint width, ref uint height) public void glk_put_buffer_uni(uint[] s, uint len) => AsyncGlk_imports.glk_put_buffer_uni(new Span((int[])(object) s, 0, (int) len)); public void glk_request_char_event(WindowHandle winId) => AsyncGlk_imports.glk_request_char_event(winId); public void glk_request_hyperlink_event(WindowHandle winId) => AsyncGlk_imports.glk_request_hyperlink_event(winId); - public unsafe void glk_request_line_event(WindowHandle win, byte* buf, uint maxlen, uint initlen) => AsyncGlk_imports.glk_request_line_event(win, new Span(buf, (int) maxlen), (int) initlen); - public unsafe void glk_request_line_event_uni(WindowHandle win, uint* buf, uint maxlen, uint initlen) => AsyncGlk_imports.glk_request_line_event_uni(win, new Span(buf, (int) maxlen), (int) initlen); + public void glk_request_line_event_uni(WindowHandle win, uint[] buf, uint maxlen, uint initlen) => AsyncGlk_imports.glk_request_line_event_uni(win, new Span((int[])(object) buf, 0, (int) maxlen), (int) initlen); public void glk_request_timer_events(uint millisecs) => AsyncGlk_imports.glk_request_timer_events((int) millisecs); public SoundChannel glk_schannel_create(uint rock) => 0; public void glk_schannel_destroy(SoundChannel chan) {} @@ -136,17 +131,10 @@ public void glk_schannel_pause(SoundChannel chan) {} public void glk_schannel_set_volume(SoundChannel chan, uint vol) {} public void glk_schannel_stop(SoundChannel chan) {} public void glk_schannel_unpause(SoundChannel chan) {} - public void glk_select(ref Event ev) - { - Task t = AsyncGlk_imports.glk_select(); - t.Wait(-1); - fill_event(ref ev); - } public void glk_set_hyperlink(uint linkval) => AsyncGlk_imports.glk_set_hyperlink((int) linkval); public void glk_set_style(Style s) => AsyncGlk_imports.glk_set_style((int) s); public void glk_set_window(WindowHandle winId) => AsyncGlk_imports.glk_set_window(winId); public StreamHandle glk_stream_open_file(FileRefHandle fileref, Glk.FileMode fmode, uint rock) => AsyncGlk_imports.glk_stream_open_file(fileref, (int) fmode, (int) rock); - public unsafe StreamHandle glk_stream_open_memory(byte* buf, uint buflen, Glk.FileMode mode, uint rock) => AsyncGlk_imports.glk_stream_open_memory(new Span(buf, (int) buflen), (int) mode, (int) rock); public void glk_stream_set_position(StreamHandle stream, int pos, SeekMode seekMode) => AsyncGlk_imports.glk_stream_set_position(stream, (int) pos, (int) seekMode); public void glk_stylehint_set(WinType wintype, Style styl, StyleHint hint, int val) => AsyncGlk_imports.glk_stylehint_set((int) wintype, (int) styl, (int) hint, (int) val); public uint glk_style_measure(WindowHandle winid, Style styl, StyleHint hint, ref uint result) => 0; @@ -173,6 +161,12 @@ public void glk_window_get_size(WindowHandle winId, out uint width, out uint hei public void garglk_set_zcolors(uint fg, uint bg) {} public string? glkunix_fileref_get_name(FileRefHandle fileref) => AsyncGlk_imports.glkunix_fileref_get_name(fileref); + public async Task GetEvent() { + await AsyncGlk_imports.glk_select(); + Event ev = new() { type = EventType.None }; + fill_event(ref ev); + return ev; + } public void SetGameName(string game) {} } diff --git a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.AsyncGlk/frankendrift.js b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.AsyncGlk/frankendrift.js index 4c9bb58..f12cd02 100644 --- a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.AsyncGlk/frankendrift.js +++ b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.AsyncGlk/frankendrift.js @@ -59,6 +59,7 @@ export class FrankenDrift { }, ], }) + //.withVirtualWorkingDirectory('/frankendrift') .create() runtime.setModuleImports('main.js', { @@ -100,7 +101,6 @@ export class FrankenDrift { glk_put_buffer_uni: val => Glk.glk_put_buffer_uni(val._unsafe_create_view()), glk_request_char_event: winId => Glk.glk_request_char_event(ids_to_objects[winId]), glk_request_hyperlink_event: winId => Glk.glk_request_hyperlink_event(ids_to_objects[winId]), - glk_request_line_event: (winId, buf, initlen) => Glk.glk_request_line_event(ids_to_objects[winId], buf._unsafe_create_view(), initlen), glk_request_line_event_uni: (winId, buf, initlen) => Glk.glk_request_line_event_uni(ids_to_objects[winId], buf._unsafe_create_view(), initlen), glk_request_timer_events: msecs => Glk.glk_request_timer_events(msecs), glk_select: async () => { @@ -123,13 +123,6 @@ export class FrankenDrift { } return 0 }, - glk_stream_open_memory: (buf, mode, rock) => { - const str = Glk.glk_stream_open_memory(buf._unsafe_create_view(), mode, rock) - if (str) { - return register_object(str) - } - return 0 - }, glk_stream_set_position: (stream, pos, seekMode) => Glk.glk_stream_set_position(ids_to_objects[stream], pos, seekMode), glk_stylehint_set: (wintype, styl, hint, val) => Glk.glk_stylehint_set(wintype, styl, hint, val), glk_tick: () => Glk.glk_tick(), diff --git a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.Gargoyle/Main.cs b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.Gargoyle/Main.cs index 63a42b1..46ff8c0 100644 --- a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.Gargoyle/Main.cs +++ b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.Gargoyle/Main.cs @@ -39,9 +39,7 @@ static class Garglk_Pinvoke [DllImport("libgarglk")] internal static extern void glk_request_hyperlink_event(WindowHandle winId); [DllImport("libgarglk")] - internal static extern unsafe void glk_request_line_event(WindowHandle win, byte* buf, uint maxlen, uint initlen); - [DllImport("libgarglk")] - internal static extern unsafe void glk_request_line_event_uni(WindowHandle win, uint* buf, uint maxlen, uint initlen); + internal static extern void glk_request_line_event_uni(WindowHandle win, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)] uint[] buf, uint maxlen, uint initlen); [DllImport("libgarglk")] internal static extern SoundChannel glk_schannel_create(uint rock); [DllImport("libgarglk")] @@ -69,8 +67,6 @@ static class Garglk_Pinvoke [DllImport("libgarglk")] internal static extern StreamHandle glk_stream_open_file(FileRefHandle fileref, Glk.FileMode fmode, uint rock); [DllImport("libgarglk")] - internal static unsafe extern StreamHandle glk_stream_open_memory(byte* buf, uint buflen, Glk.FileMode mode, uint rock); - [DllImport("libgarglk")] internal static extern void glk_stream_set_position(StreamHandle stream, int pos, SeekMode seekMode); [DllImport("libgarglk")] internal static extern void glk_stylehint_set(WinType wintype, Style styl, StyleHint hint, int val); @@ -133,8 +129,7 @@ class GarGlk: IGlk public void glk_put_buffer_uni(uint[] s, uint len) => Garglk_Pinvoke.glk_put_buffer_uni(s, len); public void glk_request_char_event(WindowHandle winId) => Garglk_Pinvoke.glk_request_char_event(winId); public void glk_request_hyperlink_event(WindowHandle winId) => Garglk_Pinvoke.glk_request_hyperlink_event(winId); - public unsafe void glk_request_line_event(WindowHandle win, byte* buf, uint maxlen, uint initlen) => Garglk_Pinvoke.glk_request_line_event(win, buf, maxlen, initlen); - public unsafe void glk_request_line_event_uni(WindowHandle win, uint* buf, uint maxlen, uint initlen) => Garglk_Pinvoke.glk_request_line_event_uni(win, buf, maxlen, initlen); + public void glk_request_line_event_uni(WindowHandle win, uint[] buf, uint maxlen, uint initlen) => Garglk_Pinvoke.glk_request_line_event_uni(win, buf, maxlen, initlen); public SoundChannel glk_schannel_create(uint rock) => Garglk_Pinvoke.glk_schannel_create(rock); public void glk_schannel_destroy(SoundChannel chan) => Garglk_Pinvoke.glk_schannel_destroy(chan); public void glk_schannel_pause(SoundChannel chan) => Garglk_Pinvoke.glk_schannel_pause(chan); @@ -143,12 +138,10 @@ class GarGlk: IGlk public void glk_schannel_set_volume(SoundChannel chan, uint vol) => Garglk_Pinvoke.glk_schannel_set_volume(chan, vol); public void glk_schannel_stop(SoundChannel chan) => Garglk_Pinvoke.glk_schannel_stop(chan); public void glk_schannel_unpause(SoundChannel chan) => Garglk_Pinvoke.glk_schannel_unpause(chan); - public void glk_select(ref Event ev) => Garglk_Pinvoke.glk_select(ref ev); public void glk_set_hyperlink(uint linkval) => Garglk_Pinvoke.glk_set_hyperlink(linkval); public void glk_set_style(Style s) => Garglk_Pinvoke.glk_set_style(s); public void glk_set_window(WindowHandle winId) => Garglk_Pinvoke.glk_set_window(winId); public StreamHandle glk_stream_open_file(FileRefHandle fileref, Glk.FileMode fmode, uint rock) => Garglk_Pinvoke.glk_stream_open_file(fileref, fmode, rock); - public unsafe StreamHandle glk_stream_open_memory(byte* buf, uint buflen, Glk.FileMode mode, uint rock) => Garglk_Pinvoke.glk_stream_open_memory(buf, buflen, mode, rock); public void glk_stream_set_position(StreamHandle stream, int pos, SeekMode seekMode) => Garglk_Pinvoke.glk_stream_set_position(stream, pos, seekMode); public void glk_stylehint_set(WinType wintype, Style styl, StyleHint hint, int val) => Garglk_Pinvoke.glk_stylehint_set(wintype, styl, hint, val); public uint glk_style_measure(WindowHandle winid, Style styl, StyleHint hint, ref uint result) => Garglk_Pinvoke.glk_style_measure(winid, styl, hint, ref result); @@ -166,6 +159,11 @@ class GarGlk: IGlk public unsafe uint glk_gestalt_ext(Gestalt sel, uint val, uint* arr, uint arrlen) => Garglk_Pinvoke.glk_gestalt_ext(sel, val, arr, arrlen); public void glk_request_timer_events(uint millisecs) => Garglk_Pinvoke.glk_request_timer_events(millisecs); + public Task GetEvent() { + Event ev = new() { type = EventType.None }; + Garglk_Pinvoke.glk_select(ref ev); + return Task.FromResult(ev); + } public void SetGameName(string game) => Garglk_Pinvoke.garglk_set_story_name(game); internal void GarglkInit(string[] argv) diff --git a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.WinGlk/Main.cs b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.WinGlk/Main.cs index 50d5e56..d952d2e 100644 --- a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.WinGlk/Main.cs +++ b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.WinGlk/Main.cs @@ -38,9 +38,7 @@ internal static class Winglk_Pinvoke [DllImport("Glk")] internal static extern void glk_request_hyperlink_event(WindowHandle winId); [DllImport("Glk")] - internal static extern unsafe void glk_request_line_event(WindowHandle win, byte* buf, uint maxlen, uint initlen); - [DllImport("Glk")] - internal static extern unsafe void glk_request_line_event_uni(WindowHandle win, uint* buf, uint maxlen, uint initlen); + internal static extern void glk_request_line_event_uni(WindowHandle win, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)] uint[] buf, uint maxlen, uint initlen); [DllImport("Glk")] internal static extern SoundChannel glk_schannel_create(uint rock); [DllImport("Glk")] @@ -68,8 +66,6 @@ internal static class Winglk_Pinvoke [DllImport("Glk")] internal static extern StreamHandle glk_stream_open_file(FileRefHandle fileref, Glk.FileMode fmode, uint rock); [DllImport("Glk")] - internal static unsafe extern StreamHandle glk_stream_open_memory(byte* buf, uint buflen, Glk.FileMode mode, uint rock); - [DllImport("Glk")] internal static extern void glk_stream_set_position(StreamHandle stream, int pos, SeekMode seekMode); [DllImport("Glk")] internal static extern void glk_stylehint_set(WinType wintype, Style styl, StyleHint hint, int val); @@ -126,8 +122,7 @@ class WindowsGlk : IGlk public void glk_put_buffer_uni(uint[] s, uint len) => Winglk_Pinvoke.glk_put_buffer_uni(s, len); public void glk_request_char_event(WindowHandle winId) => Winglk_Pinvoke.glk_request_char_event(winId); public void glk_request_hyperlink_event(WindowHandle winId) => Winglk_Pinvoke.glk_request_hyperlink_event(winId); - public unsafe void glk_request_line_event(WindowHandle win, byte* buf, uint maxlen, uint initlen) => Winglk_Pinvoke.glk_request_line_event(win, buf, maxlen, initlen); - public unsafe void glk_request_line_event_uni(WindowHandle win, uint* buf, uint maxlen, uint initlen) => Winglk_Pinvoke.glk_request_line_event_uni(win, buf, maxlen, initlen); + public void glk_request_line_event_uni(WindowHandle win, uint[] buf, uint maxlen, uint initlen) => Winglk_Pinvoke.glk_request_line_event_uni(win, buf, maxlen, initlen); public SoundChannel glk_schannel_create(uint rock) => Winglk_Pinvoke.glk_schannel_create(rock); public void glk_schannel_destroy(SoundChannel chan) => Winglk_Pinvoke.glk_schannel_destroy(chan); public void glk_schannel_pause(SoundChannel chan) => Winglk_Pinvoke.glk_schannel_pause(chan); @@ -141,7 +136,6 @@ class WindowsGlk : IGlk public void glk_set_style(Style s) => Winglk_Pinvoke.glk_set_style(s); public void glk_set_window(WindowHandle winId) => Winglk_Pinvoke.glk_set_window(winId); public StreamHandle glk_stream_open_file(FileRefHandle fileref, Glk.FileMode fmode, uint rock) => Winglk_Pinvoke.glk_stream_open_file(fileref, fmode, rock); - public unsafe StreamHandle glk_stream_open_memory(byte* buf, uint buflen, Glk.FileMode mode, uint rock) => Winglk_Pinvoke.glk_stream_open_memory(buf, buflen, mode, rock); public void glk_stream_set_position(StreamHandle stream, int pos, SeekMode seekMode) => Winglk_Pinvoke.glk_stream_set_position(stream, pos, seekMode); public void glk_stylehint_set(WinType wintype, Style styl, StyleHint hint, int val) => Winglk_Pinvoke.glk_stylehint_set(wintype, styl, hint, val); public uint glk_style_measure(WindowHandle winid, Style styl, StyleHint hint, ref uint result) => Winglk_Pinvoke.glk_style_measure(winid, styl, hint, ref result); @@ -159,6 +153,11 @@ class WindowsGlk : IGlk public unsafe uint glk_gestalt_ext(Gestalt sel, uint val, uint* arr, uint arrlen) => Winglk_Pinvoke.glk_gestalt_ext(sel, val, arr, arrlen); public void glk_request_timer_events(uint millisecs) => Winglk_Pinvoke.glk_request_timer_events(millisecs); + public Task GetEvent() { + Event ev = new() { type = EventType.None }; + Winglk_Pinvoke.glk_select(ref ev); + return Task.FromResult(ev); + } public void SetGameName(string game) => Winglk_Pinvoke.winglk_window_set_title(game); } diff --git a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkApi.cs b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkApi.cs index 2fd95ca..99450b3 100644 --- a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkApi.cs +++ b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkApi.cs @@ -250,8 +250,7 @@ public interface IGlk void glk_put_buffer_uni(uint[] s, uint len); void glk_request_char_event(WindowHandle winId); void glk_request_hyperlink_event(WindowHandle winId); - unsafe void glk_request_line_event(WindowHandle win, byte* buf, uint maxlen, uint initlen); - unsafe void glk_request_line_event_uni(WindowHandle win, uint* buf, uint maxlen, uint initlen); + void glk_request_line_event_uni(WindowHandle win, uint[] buf, uint maxlen, uint initlen); SoundChannel glk_schannel_create(uint rock); void glk_schannel_destroy(SoundChannel chan); void glk_schannel_pause(SoundChannel chan); @@ -260,12 +259,10 @@ public interface IGlk void glk_schannel_set_volume(SoundChannel chan, uint vol); void glk_schannel_stop(SoundChannel chan); void glk_schannel_unpause(SoundChannel chan); - void glk_select(ref Event ev); void glk_set_hyperlink(uint linkval); void glk_set_style(Style s); void glk_set_window(WindowHandle winId); StreamHandle glk_stream_open_file(FileRefHandle fileref, FileMode fmode, uint rock); - unsafe StreamHandle glk_stream_open_memory(byte* buf, uint buflen, FileMode mode, uint rock); void glk_stream_set_position(StreamHandle stream, int pos, SeekMode seekMode); void glk_stylehint_set(WinType wintype, Style styl, StyleHint hint, int val); uint glk_style_measure(WindowHandle winid, Style styl, StyleHint hint, ref uint result); @@ -284,6 +281,7 @@ public interface IGlk void glk_request_timer_events(uint millisecs); // And some extra functions we want that could have different implementations + Task GetEvent(); void SetGameName(string game); #pragma warning restore IDE1006 // Naming Styles } diff --git a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkHtmlWin.cs b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkHtmlWin.cs index f238b51..e903f46 100644 --- a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkHtmlWin.cs +++ b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkHtmlWin.cs @@ -115,54 +115,50 @@ public void Clear() GlkApi.glk_window_clear(glkwin_handle); } - internal unsafe string GetLineInput() + internal async Task GetLineInput() { if (IsWaiting) throw new ConcurrentEventException("Too many input events requested"); IsWaiting = true; const uint capacity = 256; - var cmdToBe = new uint[capacity]; - fixed (uint* buf = cmdToBe) + uint[] buf = GC.AllocateArray((int) capacity, true); + GlkApi.glk_request_line_event_uni(glkwin_handle, buf, capacity-1, 0); + if (_hyperlinks.Count > 0 && _hyperlinksSupported) + GlkApi.glk_request_hyperlink_event(glkwin_handle); + while (true) { - GlkApi.glk_request_line_event_uni(glkwin_handle, buf, capacity-1, 0); - if (_hyperlinks.Count > 0 && _hyperlinksSupported) - GlkApi.glk_request_hyperlink_event(glkwin_handle); - while (true) + Event ev = await GlkApi.GetEvent(); + if (ev.type == EventType.LineInput && ev.win_handle == glkwin_handle) + { + var count = (int) ev.val1; + GlkApi.glk_cancel_hyperlink_event(glkwin_handle); + IsWaiting = false; + //var dec = Encoding.GetEncoding(Encoding.Latin1.CodePage, EncoderFallback.ReplacementFallback, DecoderFallback.ReplacementFallback); + //return dec.GetString(cmdToBe, 0, count); + var result = new StringBuilder(count); + for (var i = 0; i < count; i++) + result.Append(new Rune(buf[i]).ToString()); + return result.ToString(); + } + else if (ev.type == EventType.Hyperlink && ev.win_handle == glkwin_handle) { - Event ev = new() { type = EventType.None }; - GlkApi.glk_select(ref ev); - if (ev.type == EventType.LineInput && ev.win_handle == glkwin_handle) + var linkId = ev.val1; + Event ev2 = new(); + if (_hyperlinks.ContainsKey(linkId)) { - var count = (int) ev.val1; - GlkApi.glk_cancel_hyperlink_event(glkwin_handle); + GlkApi.glk_cancel_line_event(glkwin_handle, ref ev2); IsWaiting = false; - //var dec = Encoding.GetEncoding(Encoding.Latin1.CodePage, EncoderFallback.ReplacementFallback, DecoderFallback.ReplacementFallback); - //return dec.GetString(cmdToBe, 0, count); - var result = new StringBuilder(count); - for (var i = 0; i < count; i++) - result.Append(new Rune(buf[i]).ToString()); - return result.ToString(); - } - else if (ev.type == EventType.Hyperlink && ev.win_handle == glkwin_handle) - { - var linkId = ev.val1; - Event ev2 = new(); - if (_hyperlinks.ContainsKey(linkId)) - { - GlkApi.glk_cancel_line_event(glkwin_handle, ref ev2); - IsWaiting = false; - var result = _hyperlinks[linkId]; - _hyperlinks.Clear(); - FakeInput(result); - return result; - } + var result = _hyperlinks[linkId]; + _hyperlinks.Clear(); + FakeInput(result); + return result; } - else MainSession.Instance!.ProcessEvent(ev); } + else MainSession.Instance!.ProcessEvent(ev); } } - internal uint GetCharInput() + internal async Task GetCharInput() { if (IsWaiting) throw new ConcurrentEventException("Too many input events requested"); @@ -171,8 +167,7 @@ internal uint GetCharInput() GlkApi.glk_request_char_event(glkwin_handle); while (true) { - Event ev = new() { type = EventType.None }; - GlkApi.glk_select(ref ev); + Event ev = await GlkApi.GetEvent(); if (ev.type == EventType.CharInput && ev.win_handle == glkwin_handle) { result = ev.val1; @@ -196,7 +191,7 @@ private void FakeInput(string cmd) } // Janky-ass HTML parser, 2nd edition. - public void AppendHTML(string src) + public async void AppendHTML(string src) { if (string.IsNullOrEmpty(src)) return; @@ -306,7 +301,7 @@ public void AppendHTML(string src) Clear(); break; case "waitkey": - GetCharInput(); + await GetCharInput(); break; } if (currentToken.StartsWith("font")) diff --git a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkSession.cs b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkSession.cs index 9f0de1e..73f2070 100644 --- a/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkSession.cs +++ b/FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkSession.cs @@ -39,7 +39,7 @@ public MainSession(string gameFile, IGlk glk) } // If playing a blorb file, open it with the Glk library as well - if (gameFile.EndsWith(".blorb")) + if (RuntimeInformation.ProcessArchitecture != Architecture.Wasm && gameFile.EndsWith(".blorb")) { var blorb = File.ReadAllBytes(gameFile); // Blorb files produced by ADRIFT have the wrong file length in the header @@ -71,11 +71,11 @@ public MainSession(string gameFile, IGlk glk) GlkApi.glk_request_timer_events(1000); } - public void Run() + public async void Run() { while (true) { - var cmd = _output.GetLineInput(); + var cmd = await _output.GetLineInput(); SubmitCommand(cmd); } } @@ -118,6 +118,9 @@ public void EnableButtons() { } public void ErrMsg(string message, Exception ex = null) { Console.WriteLine("Fatal error: " + message); + if (ex is not null) { + Console.WriteLine(ex); + } if (_output is null) { _output = new GlkHtmlWin(GlkApi); } @@ -226,6 +229,9 @@ public void SetGameName(string name) public void ShowCoverArt(byte[] img) { + if (_output is null) { + _output = new GlkHtmlWin(GlkApi); + } // we don't need the image data that the interpreter has provided us, // we just need to ask Glk to display image no. 1 _output.DrawImageImmediately(1);